题目来源:
题目描述:
题目描述
给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。
输入输出格式
输入格式:第一行输入一个正整数n。
以下n行每行两个字母,表示这两个字母需要相邻。
输出格式:输出满足要求的字符串。
如果没有满足要求的字符串,请输出“No Solution”。
如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案
输入输出样例
说明
【数据规模与约定】
不同的无序字母对个数有限,n的规模可以通过计算得到。
解题思路:
这题可以看作是一个判断欧拉路是否存在的问题,当输入一个字母对的时候,就从这两个字母之间连接一条双向边,然后对这张图进行判断欧拉路,因为要输出最小字典序,所以要先排序一下。欧拉路的判断就不赘述了。
代码:
#include <iostream>
#include <queue>
#include <stack>
#include <string>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
vector<int>E[100];
int zh1(char x)
{
if(x>='a'&&x<='z')return 26+int(x-'a'+1);
else return int(x-'A'+1);
}
char zh2(int x)
{
if(x<=26)return char(x+'A'-1);
else return char(x-26+'a'-1);
}
int du[100];
bool tu[100][100];
stack<int>s;
void dfs(int v)
{
for(int i=0;i<E[v].size();i++)
{
int vv=E[v][i];
if(!tu[v][vv])
{
tu[v][vv]=1;
tu[vv][v]=1;
dfs(vv);
s.push(vv);
}
}
}
int main()
{
memset(du,0,sizeof(du));
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
string a;
cin>>a;
int x=zh1(a[0]),y=zh1(a[1]);
du[x]++;
du[y]++;
E[x].push_back(y);
E[y].push_back(x);
}
int sum=0,maxn1=1e9,maxn2=1e9;
for(int i=1;i<=52;i++)
{
if(du[i]){
maxn1=min(maxn1,i);
if(du[i]%2!=0){
sum++;
maxn2=min(i,maxn2);
}
}
sort(E[i].begin(),E[i].end());
}
if(sum!=0&&sum!=2)cout<<"No Solution"<<endl;
else{
if(sum==0){
dfs(maxn1);
s.push(maxn1);
while(!s.empty())
{
cout<<zh2(s.top());
s.pop();
}
cout<<endl;
}
else{
dfs(maxn2);
s.push(maxn2);
while(!s.empty())
{
cout<<zh2(s.top());
s.pop();
}
cout<<endl;
}
}
return 0;
}