【题目描述】:
有 N 个盘子,每个盘子上写着一个仅由小写字母组成的英文单词。你需要给这些盘子安排一个合适的顺序,使得相邻两个盘子中,前一个盘子上单词的末字母等于后一个盘子上单词的首字母。请你编写一个程序,判断是否能达到这一要求。如果能,请给出一个合适的顺序。
【输入描述】:
多组数据。第一行给出数据组数T,每组数据第一行给出盘子数量N,接下去N行给出小写字母字符串,一种字符串可能出现多次。
【输出描述】:
若存在一组合法解输出“Ordering is possible.”,否则输出“The door cannot be opened.”。
【样例输入】:
3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok
【样例输出】:
The door cannot be opened.
Ordering is possible.
The door cannot be opened.
【时间限制、数据范围及描述】:
时间:1s 空间:64M
1<=N<=10^5;|S|<=1000
思路
这道题应该是求有向图的欧拉路径(俗称一笔画问题)先用并查集判断是否连通,然后判断欧拉路,即有且仅有两个度为奇数的点且起点入度=出度+1,终点入度=出度-1
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char a[1005];
int in[30],out[30],fa[30];
int find(int x)
{
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
int main()
{
int t,n,j=0,i;
scanf("%d",&t);
while(t--){
j++;
int s=0,s1=0,s2=0;
memset(in,0,sizeof(in));
memset(out,0,sizeof(out));
for(i=1;i<=26;i++)
fa[i]=i;
scanf("%d",&n);
for(i=1;i<=n;i++)
{
scanf("%s",a+1);
int len=strlen(a+1);
int x,y;
x=a[1]-'a'+1;
y=a[len]-'a'+1;
in[x]++;
out[y]++;
fa[find(x)]=find(y);
}
for(i=1;i<=26;i++)
if((in[i]||out[i])&&find(i)==i||abs(in[i]-outs[i])>1)
s++;
if(s>1)
{
printf("The door cannot be opened.\n");
continue;
}
for(i=1;i<=26;i++){
if(in[i]>out[i])
s1++;
if(in[i]>out[i])
s2++;
}
if((s1==1&&s2==1)||(s1==0&&s2==0)) printf("Ordering is possible.\n");
else printf("The door cannot be opened.\n");
}
return 0;
}