Codeforces Round #824 (Div. 2)C题

98 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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();
    }
}