题意:Valya 和 Tolya 是一对情侣, 他们的T恤和头巾上都有小写字母,但是女朋友嫌弃男朋友上T恤上的字不和她的头巾上的字一样,就很生气, 然后来了一个魔法师, 它可以购买符文, 每个符文可以让一个字母变成另外一个字母,魔法师想购买足够的符文使得他们的字母串相同, 因为买符文要钱, 现在需要求最小的购买符文数目,和符文形式, 多种答案可以输出任意一种。
题解:用并查集将有联系的字母分到一组, 然后将一组内的符文进行串联,这样每一组内的任意2个符文, 都可以由上面的字符变成下面的字符。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define fi first 5 #define se second 6 #define lson l,m,rt<<1 7 #define rson m+1,r,rt<<1|1 8 #define max3(a,b,c) max(a,max(b,c)) 9 const int INF = 0x3f3f3f3f; 10 typedef pair<int,int> pll; 11 int pre[100]; 12 int vis[100]; 13 int Find(int x) 14 { 15 if(x == pre[x]) return x; 16 return x = Find(pre[x]); 17 } 18 vector<int> ans[100]; 19 map<int,int> ccc; 20 int main() 21 { 22 ios::sync_with_stdio(false); 23 cin.tie(0); 24 cout.tie(0); 25 for(int i = 0; i < 26; i++) 26 pre[i] = i, vis[i] = 0; 27 int len; 28 string str1, str2; 29 cin >> len; 30 cin >> str1 >> str2; 31 for(int i = 0; i < len; i++) 32 { 33 if(str1[i] == str2[i]); 34 vis[str1[i]-‘a‘] = vis[str2[i]-‘a‘] = 1; 35 int u = Find(str1[i]-‘a‘), v = Find(str2[i]-‘a‘); 36 if(u == v) continue; 37 pre[u] = v; 38 } 39 int tot = 0; 40 for(int i = 0; i < 26; i++) 41 { 42 if(!vis[i]) continue; 43 int x = Find(i); 44 if(!ccc.count(x)) 45 { 46 tot++; 47 int sss = ccc.size(); 48 ccc[x] = sss + 1; 49 } 50 ans[ccc[x]].push_back(i); 51 } 52 int cnt = 0; 53 char ans1[100], ans2[100]; 54 for(int i = 1; i <= tot; i++) 55 { 56 int u = -1; 57 for(int j = 0; j < ans[i].size(); j++) 58 { 59 if(u == -1) u = j; 60 else 61 { 62 ans1[++cnt] = ans[i][u] + ‘a‘; 63 ans2[cnt] = ans[i][j] + ‘a‘; 64 u = j; 65 } 66 } 67 } 68 cout << cnt << endl; 69 for(int i = 1; i <= cnt; i++) 70 cout << ans1[i] << ‘ ‘ << ans2[i] << endl; 71 return 0; 72 }