Codeforces Round #288 (Div. 2)
给出n个长度为3的字符串,求由这些字符串组成的长度为n+2的字符串,要求前后缀有两个相同的字符
构图:例如abc,那么ab——bc
在搜索过程中,前面跟后面已经搜过的不必再搜。
有向图判断是否存在欧拉通路,并输出路径
#include<bits/stdc++.h>
const int maxm=200020;
using namespace std;
struct node{
int v,next;
}edges[maxm];int head[maxm],tot,n,pos;
inline void addedge(int u,int v,int *h){edges[tot].v=v,edges[tot].next=head[u],head[u]=tot++;}
int deg[maxm],vis[maxm];
int ans[maxm],cnt;
void init(){
memset(head,-1,sizeof(head));
memset(deg,0,sizeof(deg));
memset(vis,0,sizeof(vis));
cnt=tot=0;
}
int ch(char c){
if(isdigit(c)) return c-'0';
if(islower(c)) return c-'a'+10;
return c-'A'+36;
}
int pt(int x){
if(0<=x&&x<=9) return x+'0';
if(10<=x&&x<=35) return x+'a'-10;
return x+'A'-36;
}
bool check_degree(){
int x=0,y=0;
for(int i=0;i<maxm;++i){
if(deg[i]>1||deg[i]<-1) return false;
if(deg[i]==1) x++;
if(deg[i]==-1) y++,pos=i;
}
if(x&&y&&x+y>2) return false;
return true;
}
void euler(int u){
for(int i=head[u];i!=-1;i=head[u]){
if(!vis[i]){
vis[i]=1;
head[u]=edges[i].next;
euler(edges[i].v);
}
}
ans[cnt++]=u;
}
int main()
{
init();
cin>>n;
char s[4];
for(int i=0;i<n;++i){
scanf("%s",s);
int u=ch(s[0])*62+ch(s[1]);
int v=ch(s[1])*62+ch(s[2]);
if(i==n-1) pos=u;
addedge(u,v,head);
deg[u]--;
deg[v]++;
}
if(check_degree()){
euler(pos);
if(cnt<n+1) {printf("NO\n");return 0;}
printf("YES\n");
printf("%c%c",pt(ans[cnt-1]/62),pt(ans[cnt-1]%62));
for(int i=cnt-2;i>=0;--i) printf("%c",pt(ans[i]%62));
cout<<endl;
}else printf("NO\n");
return 0;
}