持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
题意:给你一个字符串要求输出一个字符串,输出的字符串要满足两个要求中的一个,一个是他和给出的字符串不能构成循环,一个是构成循环但是这个循环要满足26个字符串全在里面。注意输出的字符串要字典序最小 例如:bc,输出ab,而a->b->c这个没有构成循环,你不能输出cb因为b->c->b构成了循环但是他没有包含26个字母 题解:我们可以开一个循环从a~z每次遍历看看哪一个没有被用到,然后判断这个字符可不可以满足条件,而判断这个条件要用到并查集的思想,就是他的从一个节点到另一个节点的跳转,这里一般是用数组存,但是判断的时候要特别注意一下会不会出现判断不到的情况 代码:
#include <bits/stdc++.h>
using namespace std;
int a[100100];
int n;
map<int,int>mp,mp1;
bool check(int u)
{
int x = 0;
for(int i = 1;i <= u;i ++)
{
int res = a[i],pos = a[i];
x = 0;
while(1)
{
//cout << x << '\n';
x ++;
if(mp[pos])
pos = mp[pos];
else
break;
if(pos == res)
{
if(x < 26)
return true;
else
break;
}
}
}
return false;
}
void solve()
{
mp.clear();
mp1.clear();
cin >> n;
string s;
cin >> s;
for(int i = 0;i < n;i ++)
{
int x = s[i] - 'a' + 1;
a[i+1] = x;
}
for(int i = 1;i <= n;i ++)
{
if(mp[a[i]])
continue;
for(int j = 1;j <= 26;j ++)
{
if(j == a[i])
continue;
if(mp1[j])
continue;
mp[a[i]] = j;
mp1[j] = 1;
if(check(i))
{
mp1[j] = 0;
mp[a[i]] = 0;
continue;
}
break;
}
}
for(int i = 1;i <= n;i ++ )
{
char ans = mp[a[i]] + 'a' - 1;
cout << ans;
}
cout << '\n';
}
int main()
{
int t;
cin >> t;
while(t--)
{
solve();
}
}