题目描述
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
输入格式
第一行输入一个正整数n。
以下n行每行两个字母,表示这两个字母需要相邻。
输出格式
输出满足要求的字符串。
如果没有满足要求的字符串,请输出“No Solution”。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案
输入输出样例
输入 #1复制
4 aZ tZ Xt aX
输出 #1复制
XaZtX
说明/提示
【数据规模与约定】
不同的无序字母对个数有限,n的规模可以通过计算得到。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <map>
#include <cstdio>
#include <bitset>
using namespace std;
const int N=300,M=N*2;
//std::ios::sync_with_stdio(false); ¶ÁÈëÓÅ»¯
struct node{
int a,b,w;
bool operator <(const node &W){
return w<W.w;
}
}E[N];
int n,m,ans;
int e[N],h[N],ne[N],idx;
int d[N],seq[N];
char str[4],G[N][N],f[N];
vector <char> res;
void add(int a,int b)
{
e[idx]=b,ne[idx]=h[a],h[a]=idx++;
}
int find(int x)
{
if(x!=f[x])
f[x]=find(f[x]);
return f[x];
}
void dfs(int x)
{
for(int i=1;i<=N;i++)
{
if(G[x][i]){
G[x][i]=G[i][x]=0;
dfs(i);
}
}
res.push_back(x);
}
int main()
{
cin>>n;
for(int i=1;i<=N;i++) f[i]=i;
for(int i=1;i<=n;i++)
{
scanf("%s",str);
G[str[0]][str[1]]=G[str[1]][str[0]]=1;//假设是一张无向图上的一条边,因为是无序的
d[str[0]]++,d[str[1]]++;//入度加1
int fy=find(str[0]),fx=find(str[1]);
f[fx]=fy;//合并两个集合
}
int sum=0;
for(int i=1;i<N;i++)
{
if(f[i]==i&&d[i])
sum++;
}
if(sum>1)
puts("No Solution");//有两个以上的连通块
else
{
int he=0,cnt=0;
for(int i=1;i<=N;i++)
{
if((d[i]&1))
{
cnt++;
if(!he)
he=i;//取字典序最小的为起点
}
}
if(cnt&&cnt!=2)
{
puts("No Solution");//必须有两个点的度数为奇数否则不是欧拉图
}
else
{
if(!he)
{
for(int i=1;i<=N&&!he;i++)
if(d[i])
he=i;
}
dfs(he);
for(int i=res.size()-1;i>=0;i--)
printf("%c",res[i]);//因为是递归回溯存的边,所以要倒叙输出
cout<<endl;
}
}
return 0;
}