公式

A - パスワード照合 / Password Verification 解説 by admin

Claude 4.6 Opus (Thinking)

Overview

This is a problem where only some positions of a password are known, and we need to determine whether each candidate string matches all of those known positions.

Analysis

The key point of this problem is that while the entire password is unknown, we have \(M\) pieces of information stating “the character at position \(P_i\) is \(C_i\).” To determine whether a candidate string should be accepted, we only need to check the recovered positions — all other positions can be anything.

For example, consider \(N = 5\) with recovered data: “the 2nd character is a” and “the 4th character is c.”

  • Candidate xaxcx → 2nd character is a, 4th character is c, both match → Yes
  • Candidate xbxcx → 2nd character is b, mismatch → No

A naive approach that scans the entire password (\(N\) characters) each time would also work, but it suffices to check only the \(M\) recovered positions, avoiding unnecessary comparisons.

In this problem, \(Q \leq 10^3\) and \(M \leq N \leq 10^5\), so even checking \(M\) positions for each candidate results in at most \(10^3 \times 10^5 = 10^8\) operations. However, since dictionary traversal and index access are lightweight, this is fast enough.

Algorithm

  1. Read recovered data: Store the \(M\) pairs \((P_i, C_i)\) in a dictionary (hash map). The key is the 0-indexed position \(P_i - 1\), and the value is the character \(C_i\).

  2. Judge each candidate string: For each of the \(Q\) candidate strings \(T\), check whether T[pos] matches the corresponding character ch for every position pos stored in the dictionary.

    • If all match, output Yes
    • If any mismatch is found, output No (terminate early)
  3. Output results: Output Yes or No for each candidate.

Complexity

  • Time complexity: \(O(M + Q \cdot M)\)
    • \(O(M)\) for reading the recovered data, \(O(M)\) for checking \(M\) positions per candidate string, repeated \(Q\) times.
  • Space complexity: \(O(N + M)\)
    • \(M\) entries in the dictionary, and up to \(N\) characters for each candidate string.

Implementation Notes

  • 1-indexed → 0-indexed conversion: Since positions are given as 1-indexed in the problem statement, we convert to 0-indexed by storing \(P_i - 1\) in the dictionary.

  • Early break: When a mismatch is found, we break out of the loop immediately to avoid unnecessary comparisons.

  • Fast input processing: By reading all input at once with sys.stdin.buffer.read() and splitting into tokens with split(), we avoid I/O bottlenecks when handling large inputs.

    Source Code

import sys

def main():
    input_data = sys.stdin.buffer.read().decode()
    tokens = input_data.split()
    idx = 0
    N = int(tokens[idx]); idx += 1
    M = int(tokens[idx]); idx += 1
    Q = int(tokens[idx]); idx += 1
    
    known = {}
    for _ in range(M):
        p = int(tokens[idx]); idx += 1
        c = tokens[idx]; idx += 1
        known[p - 1] = c
    
    out = []
    for _ in range(Q):
        T = tokens[idx]; idx += 1
        ok = True
        for pos, ch in known.items():
            if T[pos] != ch:
                ok = False
                break
        out.append("Yes" if ok else "No")
    
    sys.stdout.write("\n".join(out) + "\n")

main()

This editorial was generated by claude4.6opus-thinking.

投稿日時:
最終更新: