Codeforces Round #824 (Div. 2) C. Phase Shift
Posted on 2022-10-05 20:55 Capterlliar 阅读(89) 评论(0) 编辑 收藏 举报(有点难以描述的)题意:给出一串字母,为每一个字母找一个映射,要求:1)所有的映射连起来形成一个且只有一个环;2)这个环内包含26个字母;3)映射后形成的新字符串字典序最小。
解:随便找两个26个字母的排列,再随便映射一下,可以发现:不管怎么样都是能形成环的,就是有几个的问题。题目要求只有一个,那就不要让新的字母映射到已经用过的字母上,可以用并查集实现。至于字典序尽量选小的就好。注意有字符串中26个不同字母的时候特判一下,因为到最后一个的时候不管怎么样前面的都用过一次了,这时候要把最后一个映射给没用过的。
可能还是看代码清楚一点:

#include<bits/stdc++.h> using namespace std; #define ll long long #define maxx 200005 #define inf 1000000009; #define mod 998244353 char s[maxx]; int fa[30]; int find(int x){ return fa[x]==x?x:fa[x]= find(fa[x]); } signed main(){ int T; cin>>T; while(T--){ int n; scanf("%d",&n); scanf("%s",s); char cnt[30]={0}; string ans; for(int i=0;i<n;i++){ if(!cnt[s[i]-'a']){ ans+=s[i]; cnt[s[i]-'a']++; } } for(int i=0;i<26;i++) fa[i]=i; int res[30]={0},cnt2[30]={0}; for(int i=0;i<ans.length();i++){ for(int j=0;j<26;j++){ if(find(ans[i]-'a')!=find(j)&&!cnt2[j]){ res[ans[i]-'a']=j; cnt2[j]++; fa[ans[i]-'a']=j; break; } } } if(ans.length()==26){ for(int i=0;i<26;i++){ if(!cnt2[i]){ res[ans[ans.length()-1]-'a']=i; break; } } } for(int i=0;i<n;i++) s[i]=res[s[i]-'a']+'a'; printf("%s\n",s); } return 0; }
标签:
日常题
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?