​J. Pointer Analysis​

读题的时候一定要仔细啊…比赛的时候读错题,写了半天都是 wa 的

其实只要把思路理清了,实现起来就很方便了。

对于每一个大写字母,只需要保存其可指向的对象即可,因为最多只有26个,因此直接用状态压缩即可,而且对于合并操作也很方便。

// Created by CAD
#include <bits/stdc++.h>
using namespace std;

char l[200][10],r[200][10];
const int maxn=26*26+26;
int ans[maxn];
int main(){
int n;scanf("%d",&n);
for(int i=0;i<n;++i)
scanf("%s = %s",l[i],r[i]);
for(int t=0;t<26*maxn;++t)
for(int i=0;i<n;++i)
if(islower(r[i][0])) //A=a
ans[l[i][0]-'A']|=1<<(r[i][0]-'a');
else if(!l[i][1]&&!r[i][1]) //A=B
ans[l[i][0]-'A']|=ans[r[i][0]-'A'];
else if(l[i][1]=='.') //A.f=B
for(int j=0;j<26;++j){
if(ans[l[i][0]-'A']>>j&1)
ans[26+j*26+l[i][2]-'a']|=ans[r[i][0]-'A'];
}
else //A=B.f
for(int j=0;j<26;++j)
if(ans[r[i][0]-'A']>>j&1)
ans[l[i][0]-'A']|=ans[26+j*26+r[i][2]-'a'];
for(int i=0;i<26;++i){
cout<<char('A'+i)<<": ";
for(int j=0;j<26;++j)
if(ans[i]>>j&1) cout<<char('a'+j);
cout<<endl;
}
}

CAD加油!欢迎跟我一起讨论学习算法