样例过了求hack
Problem D: 单词游戏
Time Limit: 1 Sec Memory Limit: 32 MB
Description
有 N个盘子,每个盘子上写着一个仅由小写字母组成的英文单词。你需要给这些盘子安排一个合适的顺序,使得相邻两个盘子中,前一个盘子上单词的末字母等于后一个盘子上单词的首字母。请你编写一个程序,判断是否能达到这一要求。如果能,请给出一个合适的顺序。
Input
多组数据。第一行给出数据组数 T,每组数据第一行给出盘子数量 N,接下去 N 行给出小写字母字符串,一种字符串可能出现多次。
Output
若存在一组合法解输出"Ordering is possible.",否则输出"The door cannot be opened."。
Sample Input
3
2
acm
ibm
3
acm
malform
mouse
2
ok
ok
Sample Output
The door cannot be opened.
Ordering is possible.
The door cannot be opened.
Sample Input2
5
2
acb
bac
2
bac
acb
2
abc
def
3
abc
cba
cba
4
abc
cba
abc
abc
Sample Output2
Ordering is possible.
Ordering is possible.
The door cannot be opened.
Ordering is possible.
The door cannot be opened.
HINT
1≤N≤10^5,∣S∣≤1000
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define M 200001
#define can "Ordering is possible."
#define cant "The door cannot be opened."
#define clean(a) memset(a, 0, sizeof(a))
using namespace std;
struct E { int to, next; } e[M];
char s[1001];
int T, n, u, v, st, dif_1, dif1;
int ins[26], outs[26], head[26], tot;
bool exist[26], vis[26], pd;
void adde(int x, int y)
{
e[++tot].next = head[x];
head[x] = tot;
e[tot].to = y;
}
void dfs(int u)
{
vis[u] = true;
for(int i=head[u]; i; i=e[i].next)
{
int v = e[i].to;
if(!vis[v])
dfs(v);
}
}
int main()
{
scanf("%d", &T);
while(T--)
{
tot = dif_1 = dif1 = 0;
pd = true;
clean(ins);
clean(outs);
clean(head);
clean(exist);
clean(vis);
scanf("%d", &n);
if(n==1)
{
scanf("%s", s);
puts(can);
continue;
}
for(int i=1; i<=n; i++)
{
scanf("%s", s);
u = s[0]-'a';
v = s[strlen(s)-1]-'a';
outs[u]++; ins[v]++;
exist[u] = exist[v] = true;
adde(u, v), adde(v, u);
}
for(int i=0; i<26; i++)
{
int dif = ins[i]-outs[i];
if(abs(dif)>1)
{
pd = false;
break;
}
else if(dif == -1) dif_1 ++, st = i;
else if(dif == 1) dif1 ++;
}
if(!pd || dif_1>1 || dif1>1 || (dif_1 ^ dif1)==1)
{
puts(cant);
continue;
}
dfs(st);
for(int i=0; i<26; i++)
{
if(exist[i] && !vis[i])
{
pd = false;
break;
}
}
if(pd) puts(can);
else puts(cant);
}
return 0;
}