Play on Words——玩文字游戏

Problem Description

Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because there is no other way to open the doors, the puzzle is very important for us.

There is a large number of magnetic plates on every door. Every plate has one word written on it. The plates must be arranged into a sequence in such a way that every word begins with the same letter as the previous word ends. For example, the word ``acm'' can be followed by the word ``motorola''. Your task is to write a computer program that will read the list of words and determine whether it is possible to arrange all of the plates in a sequence (according to the given rule) and consequently to open the door.

 

Input

The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing a single integer number Nthat indicates the number of plates (1 <= N <= 100000). Then exactly Nlines follow, each containing a single word. Each word contains at least two and at most 1000 lowercase characters, that means only letters 'a' through 'z' will appear in the word. The same word may appear several times in the list.

 

Output

Your program has to determine whether it is possible to arrange all the plates in a sequence such that the first letter of each word is equal to the last letter of the previous word. All the plates from the list must be used, each exactly once. The words mentioned several times must be used that number of times.
If there exists such an ordering of plates, your program should print the sentence "Ordering is possible.". Otherwise, output the sentence "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.

描述:

一些秘密的门包含了一个非常有趣的字谜。考古学家必须解决这个问题才能打开那扇门。因为没有其他方法可以打开这些门,这个谜题对我们来说非常重要。
每扇门上都有大量的磁板。每个盘子上都写着一个字。盘子必须按照顺序排列,每个单词的开头都与前一个单词结尾的字母相同。例如,"ACM"一词后面可以加上"motorola"一词。您的任务是编写一个计算机程序,该程序将读取单词列表,并确定是否可能按照给定的规则将所有的盘子按顺序排列,从而打开门。

输入:

输入由t测试用例组成。它们(t)的数目在输入文件的第一行给出。每个测试用一行开头,其中包含一个整数n来指示板的数目(1<=N<=100000)。然后精确的Nline跟随,每个包含一个单词。每个单词至少包含两个字符,最多1000个小写字符,这意味着只有字母“a”到“z”才会出现在单词中。同样的词可能在列表中出现数次。

输出:

您的程序必须确定是否有可能将所有的盘子排列成一个顺序,使得每个单词的第一个字母等于前一个单词的最后一个字母。名单上的所有磁牌都必须使用,每个都必须使用一次。多次提到的词必须用那个次数。
如果有这样的排序,您的程序应该打印句子“排序是可能的。Ordering is possible”..否则,输出“门不能打开The door cannot be opened”的句子。
 给出N个字符串,当一个字符串的末尾单词跟另一个字符串的首单词相等时,这两个字符串可以首尾连接。问是否存在一种方案使得这些字符串连成一个序列。

AC码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
char te[1100];
int pre[28];
int vis[28],du[28];
int T,n,x,y,len,t,flag;
void de()
{
	for(int i=0;i<28;i++)
		pre[i]=i;
}
int find(int x)  
{  
    if (x != pre[x])  
    {  
        pre[x] = find(pre[x]); 
    }  
    return pre[x];  
}  // return pre[x] == x?x:pre[x] = find(pre[x]); //可以用这句代替 
int main(){
	
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		de();
		memset(vis,0,sizeof(vis));
		memset(du,0,sizeof(du));
	
		flag=1;
		for(int i=0;i<n;i++)
		{
			scanf("%s",te);//输入一串字符 
			len=strlen(te);
			x=te[0]-'a';y=te[len-1]-'a';
			vis[y]=vis[x]=1;
			du[x]++;du[y]--;
			x=find(x);	
			pre[y]=x;	
		}
		for(int i=0;i<26;i++)//再次压缩路径
			find(i);
		for(int i=0;i<26;i++)
			if(vis[i]==1) {
			t=pre[i]; break;
			}
		for(int i=0;i<26;i++){
			if(vis[i]==1&&t!=pre[i]) {
			     flag=0;break;
			}	
			
		}
		if(flag==0) {cout<<"The door cannot be opened."<<endl;
			 
		} 
		else{
				int fr=0,be=0,i=0;
					for(;i<26;i++){
						if(du[i]==1) fr++;
						else if(du[i]==-1) be++;
						else if(du[i]!=0){
						break;
						}
					}
				if(i!=26) cout<<"The door cannot be opened."<<endl;
				else if((fr==1&&be==1)||(fr==0&&be==0)) cout<<"Ordering is possible."<<endl; 
				else cout<<"The door cannot be opened."<<endl;
		}
		
		
	}

return 0;} 

猜你喜欢

转载自blog.csdn.net/hanyue0102/article/details/81734974