题目描述

给定n个各不相同的无序字母对(区分大小写,无序即字母对中的两个字母可以位置颠倒)。请构造一个有n+1个字母的字符串使得每个字母对都在这个字符串中出现。

输入输出格式

输入格式:

 

第一行输入一个正整数n。

以下n行每行两个字母,表示这两个字母需要相邻。

 

输出格式:

 

输出满足要求的字符串。

如果没有满足要求的字符串,请输出“No Solution”。

如果有多种方案,请输出前面的字母的ASCII编码尽可能小的(字典序最小)的方案

 

输入输出样例

输入样例#1: 
4
aZ
tZ
Xt
aX
输出样例#1: 
XaZtX
 
这道题是欧拉回路?差不多吧。先判断每个点的度数,如果基数点的个数不为2或0,就是无解了。然后跑图就好了。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int g[55][55], deg[55];
vector<int > ans;
int tonum(char x){                                               //字符转为数字
    if(x<='Z') return x-'A'+1;
    return x-'a'+1+26;
}
char tochar(int x){                                                //数字转字符
    if(x<=26) return x+'A'-1;
    return x+'a'-1-26;
}
void dfs(int here){                                                //从单点开始的欧拉回/链路dfs
    for(int i=1;i<=52;i++)                                  //确保字典序
        if(g[here][i]){
            g[here][i]=0;                                 //删除边线
            g[i][here]=0;
            dfs(i);
        }
    ans.push_back(here);                                   //添加顶点到回/链路中
}
int main(){
    int n, u1=100, u2=100, cnt=0;
    cin>>n;
    for(int i=1;i<=n;i++){                                       //建图
        char x, y;
        cin>>x>>y;
        if(!g[tonum(x)][tonum(y)]){
            g[tonum(x)][tonum(y)]=1;
            g[tonum(y)][tonum(x)]=1;
            deg[tonum(x)]++;                              //出入度统计
            deg[tonum(y)]++;
        }
    }
    for(int i=1;i<=52;i++)                                                                     //统计奇点数
        if(deg[i]&1){                          
            cnt++;
            u1=min(u1, i);                                                                     //满足字典序
        }
        else if(deg[i]!=0) u2=min(u2, i);
    if(cnt!=0&&cnt!=2){ cout<<"No Solution"<<endl; return 0; }             //奇点数不满足(2)
    if(cnt==0) dfs(u2);
    else dfs(u1);
    reverse(ans.begin(), ans.end());                                                             //反转回/链路
    if(ans.size()>n+1){ cout<<"No Solution"<<endl; return 0; }                //代表不连通图情况(1)
    for(int i=0;i<ans.size();i++)
        cout<<tochar(ans[i]);
    cout<<endl;
    return 0;
}

 

posted on 2017-10-24 19:52  杯具-  阅读(137)  评论(0编辑  收藏  举报