Codeforces1303C. Perfect Keyboard

本题可以转换成图论来做,每两个相邻点连一条边,然后统计每一个点的degree,如果>=2说明有一个点要相邻三个点,不满足题意,然后找出每个degree<2的点,这些点可以作为一段的起点,然后依次dfs添加,如果26个字母有一个没有dfs到的,就无解

#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) ((x)&(-x))
typedef long long LL;

char str[205];
bool connect[30][30], vis[30];
int degree[30];
string ans;

void dfs(int u) {
    if(vis[u]) return;
    vis[u] = true, ans += (char)(u+'a');
    for(int i = 0; i <= 25; ++i)
        if(!vis[i] && connect[u][i]) dfs(i);
}

void run_case() {
    cin >> str;
    ans = "";
    memset(connect, 0, sizeof(connect)), memset(degree, 0, sizeof(degree));
    memset(vis, 0, sizeof(vis));
    int siz = strlen(str);
    for(int i = 0; i < siz-1; ++i) {
        int a = str[i] - 'a', b = str[i+1] - 'a';
        connect[a][b] = connect[b][a] = true;
    }
    for(int i = 0 ; i <= 25; ++i)
        for(int j = 0; j <= 25; ++j)
            if(connect[i][j]) degree[i]++;
    for(int i = 0; i <= 25; ++i)
        if(degree[i] > 2) {
            cout << "NO\n";
            return;
        }
    for(int i = 0; i <= 25; ++i)
        if(degree[i] < 2 && !vis[i]) dfs(i);
    for(int i = 0; i <= 25; ++i)
        if(!vis[i]) {
            cout << "NO\n";
            return;
        }
    cout << "YES\n" << ans << "\n";
}

int main() {
    ios::sync_with_stdio(false), cin.tie(0);
    //cout.setf(ios_base::showpoint);cout.precision(10);
    int t; cin >> t;
    while(t--)
    run_case();
    cout.flush();
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/GRedComeT/p/12303798.html