Problem Description
给你T组数据,每组数据给你一个n,接下来有n行,每行代表一个字符串,问你能不能把他们连接起来,这个串的尾字母,等于另外一个串的首字母,他们就能连起来。
代码: 典型的判断欧拉回路的题目,核心:判断欧拉路要满足,该图是连通,而且度数为奇数的点,两个或者没有,为了防止重复的字符串,所以还要满足入度和出度差值的绝对值,不能大于1
#include<bits/stdc++.h>
using namespace std;
int Map[30][30], ru[30], chu[30];//图,入度,出度
int vis[30];//标记是否走过
void dfs(int u)
{
vis[u] = 1;//走过标记1
for(int i = 0; i < 26; i++)
{
if(Map[u][i] && !vis[i])
dfs(i);
}
}
int main()
{
int T, n, len, i;
char str[1005];
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
memset(Map, 0, sizeof(Map));//全部初始化
memset(vis, 0, sizeof(vis));
memset(ru, 0, sizeof(ru));
memset(chu, 0, sizeof(chu));
while(n--)
{
scanf("%s", str);
len = strlen(str);
Map[str[0] - 'a'][str[len - 1] - 'a']++;//首字母,尾字母,首指向尾
chu[str[0] - 'a']++;//首字母,出度
ru[str[len - 1] - 'a']++;//尾字母,入度
}
for(i = 0; i < 30; i++)
{
if(chu[i])
{
dfs(i);//遍历一遍,用于一会儿判断连通
break;
}
}
int sum, flag = 0;
for(i = 0; i < 26; i++)
{
sum = 0;
sum = chu[i] + ru[i];
if(abs(chu[i] - ru[i]) > 1) break;//如果差值大于1
if(chu[i] || ru[i])
{
if(!vis[i]) break;//如果不连通
}
if(sum % 2 != 0)//记录奇数点有几个
flag++;
}
if(i == 26)//输出
{
if(flag == 2 || flag == 0)
printf("Ordering is possible.\n");
else
printf("The door cannot be opened.\n");
}
else printf("The door cannot be opened.\n");
}
}