C - 化学反応シミュレーション / Chemical Reaction Simulation Editorial by admin
Claude 4.6 Opus (Thinking)Overview
This problem asks you to simulate the process of inserting elements one by one into a test tube (stack), where if the top element of the stack and the newly added element match a reaction pattern, both are annihilated. You need to determine the final contents of the test tube.
Analysis
Key Insight: Straightforward Simulation with a Stack
Reading the problem statement carefully, two points are crucial:
- The test tube has a stack structure: New elements are always placed on top (at the end).
- Chain reactions do not occur: At most one annihilation happens per insertion. After an annihilation, there is no re-check against the newly exposed top element.
Thanks to these two points, the problem reduces to a simple simulation of “either push onto the stack, or pop if the condition is met.”
Verification with a Concrete Example
For example, if \(S = \) ABBA and the reaction patterns are \((A, B)\) and \((B, A)\):
| Input char | Stack state (before) | Decision | Stack state (after) |
|---|---|---|---|
| A | [] |
Empty, so push | [A] |
| B | [A] |
\((A, B)\) is a reaction pattern → pop | [] |
| B | [] |
Empty, so push | [B] |
| A | [B] |
\((B, A)\) is a reaction pattern → pop | [] |
The final result is empty, so we output EMPTY.
Is the Naive Approach Sufficient?
For each character, we check whether it reacts with the top of the stack. The key is how to implement the reaction pattern lookup. Since there are at most \(676\) (\(26 \times 26\)) reaction patterns, storing them in a set (hash set) allows \(O(1)\) lookups. Therefore, the overall complexity is \(O(N)\), which is fast enough even for \(N \leq 10^6\).
Algorithm
- Preprocessing: Store the \(M\) reaction patterns \((X_k, Y_k)\) in a hash set (Python’s
set). - Simulation: Process the string \(S\) one character at a time from the beginning.
- If the stack is non-empty and
(top of stack, current character)is in the reaction pattern set → remove the top element from the stack (pop). - Otherwise → add the current character to the stack (push).
- If the stack is non-empty and
- Output: If the stack is empty, output
EMPTY; otherwise, concatenate and output the contents of the stack.
Complexity
- Time complexity: \(O(N + M)\)
- Reading the reaction patterns takes \(O(M)\), and for each character of the string, the stack operation and reaction check each take \(O(1)\), totaling \(O(N)\).
- Space complexity: \(O(N + M)\)
- The stack stores at most \(O(N)\) characters, and the reaction pattern set stores \(O(M)\) entries.
Implementation Notes
Fast input: Since \(N\) can be as large as \(10^6\), in Python we use
sys.stdin.buffer.read()to read all input at once, reducing I/O overhead.Storing reaction patterns: By inserting tuples
(X, Y)into aset, \(O(1)\) lookups are possible. Note that reaction patterns are directional — \((X, Y)\) and \((Y, X)\) are different.Confirming no chain reactions: The problem statement explicitly states that “after an annihilation occurs, no further reaction check is performed against the newly exposed top element.” Therefore, only one check is needed per insertion. If this condition were absent, we would need to loop and re-check after each pop, but that is not required in this problem.
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
S = tokens[idx]; idx += 1
react = set()
for _ in range(M):
X = tokens[idx]; idx += 1
Y = tokens[idx]; idx += 1
react.add((X, Y))
stack = []
for ch in S:
if stack and (stack[-1], ch) in react:
stack.pop()
else:
stack.append(ch)
if stack:
print(''.join(stack))
else:
print('EMPTY')
main()
This editorial was generated by claude4.6opus-thinking.