Codeforces-1688 C: Manipulating History
题目传送门:Codeforces-1688 C
题目
题目截图
样例描述
题目大意
字符串 s s s 的初始长度为 1 1 1,每一次可以将里面的子串 t 2 i − 1 t_{2i-1} t2i−1 替换为 t 2 i t_{2i} t2i,如果出现多次 t 2 i − 1 t_{2i-1} t2i−1,那么只有一个被替换为 t 2 i t_{2i} t2i。现在给出最终结果,和被打乱的 t t t 序列,问初始字符串是多少。
题目解析
这道题最大的问题是读题。初始长度为
1
1
1,代表初始字符串其实就是一个字符;每一次替换字符串中的子串,说明
t
2
i
−
1
t_{2i-1}
t2i−1 一定出现在当前字符串中,且在当前轮将被替换一次。题目保证初始字符串存在。
那么,整个替换过程中,若我们假设变换过程中只有一个字符
c
c
c, 在之后其变换状态应该是从没有到有(
c
∉
t
2
i
−
1
,
c
∈
t
2
i
c \notin t_{2i-1},c \in t_{2i}
c∈/t2i−1,c∈t2i)、从有到有(
c
∈
t
2
i
−
1
,
c
∈
t
2
i
c \in t_{2i-1},c \in t_{2i}
c∈t2i−1,c∈t2i)、从有到没有(
c
∈
t
2
i
−
1
,
c
∉
t
2
i
c \in t_{2i-1},c \notin t_{2i}
c∈t2i−1,c∈/t2i),可以看到,每次交换的串中出现一次
c
c
c,字符串中
c
c
c 的出现情况就会变化。
这种轮换可以推广到题目,我们把所有相关字符串通过填充空字符,变成等长的。可以发现,若初始字符是
c
c
c,结果字符串有奇数个
c
c
c,那么
2
t
2t
2t 个替换字符串里必然有偶数个
c
c
c, 依此类推,能够知道,所有输入中,出现奇数次数的字符就是结果,其余字符必然出现偶数次,那么我们直接用异或,把偶数次字符筛掉,就能得到最终答案。
Code
#include <bits/stdc++.h>
using namespace std;
int main() {
int T, n; string s;
cin >> T;
while(T--) {
cin >> n;
n = 2 * n + 1;
char ans = 0;
while(n--) {
cin >> s;
for(auto k : s) ans ^= k;
}
cout << ans << endl;
}
return 0;
}