Nhiều người lầm tưởng macro trong C hoạt động như biến — nghĩa là nếu định nghĩa lại A, mọi macro đã dùng A trước đó sẽ "cập nhật" theo giá trị mới. Thực tế không phải vậy: khi macro B được định nghĩa dựa trên A, giá trị của A được "chốt" (bake-in) ngay tại thời điểm định nghĩa B; định nghĩa lại A sau đó không ảnh hưởng đến B đã có.
Cho n định nghĩa macro object-like theo thứ tự NAME=EXPR, trong đó EXPR là một biểu thức số học chỉ gồm hằng số nguyên, dấu ngoặc (), các toán tử + - *, và tên của các macro đã được định nghĩa trước đó (macro có thể được định nghĩa lại nhiều lần — mỗi lần định nghĩa lại tạo ra một giá trị mới, độc lập với các macro khác đã "chốt" giá trị cũ). Khi định nghĩa NAME=EXPR, hãy thay mọi tên macro xuất hiện trong EXPR bằng giá trị số nguyên hiện tại (tại thời điểm này) của macro đó, rồi tính ra giá trị nguyên cuối cùng và gán cho NAME (ghi đè nếu NAME đã tồn tại).
Sau khi xử lý xong n định nghĩa, cho một dòng gồm m token. Với mỗi token: nếu token trùng tên một macro đã từng được định nghĩa, thay bằng giá trị cuối cùng (theo lần định nghĩa gần nhất) của macro đó; ngược lại giữ nguyên token.
Ví dụ: A=3, B=A*2 (chốt B=6), A=10 (định nghĩa lại, không ảnh hưởng B), C=A+B (dùng A=10 mới nhất, B=6 đã chốt, ra C=16). Dòng truy vấn A B C cho kết quả 10 6 16.
Dòng đầu tiên chứa số nguyên n (0≤n≤200). n dòng tiếp theo, mỗi dòng có dạng NAME=EXPR (không khoảng trắng thừa), trong đó mọi tên macro xuất hiện trong EXPR đã được định nghĩa ở một dòng trước đó, và kết quả tính toán luôn là số nguyên, độ lớn không vượt quá 1015 theo giá trị tuyệt đối.
Dòng tiếp theo chứa số nguyên m (0≤m≤1000). Dòng cuối chứa m token cách nhau khoảng trắng (rỗng nếu m=0).
In ra một dòng là kết quả sau khi thay thế các token trùng tên macro bằng giá trị cuối cùng của chúng, cách nhau một khoảng trắng (dòng rỗng nếu m=0).
Ví dụ:
Đầu vào:
4
A=3
B=A*2
A=10
C=A+B
3
A B C
Đầu ra:
10 6 16
Đầu vào:
2
X=(2+3)*4
Y=X-1
3
X Y foo
Đầu ra:
20 19 foo
Đang tải editor...