本题可以转换成图论来做,每两个相邻点连一条边,然后统计每一个点的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 "; 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 "; return; } cout << "YES " << ans << " "; } 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; }