成语接龙
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0 Accepted Submission(s): 0
Problem Description
小Z和大Z最近沉迷于成语接龙游戏,他们准备把成语接龙的规则修改一下。规则是这样的:有两个字符串,如果第一个字符串是第二个字符串的子串(也就是第一个字符串在第二个字符串中可以找到),那么第一个字符串后面可以接第二个字符串。问题来了,现在有n个字符串,你可以把n个字符串的顺序进行重组,使得这n个字符串可以成语接龙,即第一个字符串后面可以接第二个字符串,第二个字符串后面可以接第三个字符串,......,第n-1个字符串后面可以跟第n个字符串。问你能不能把n个字符串顺序重组,满足这n个字符串可以成语接龙。
Input
第一行为一个整数T,代表有T组样例。(T<=10)
每组数据中:
第一行为一个整数N,表示有N个字符串。(N<=100)
接下来n行,每行一个字符串,每个字符串长度小于等于100。
Output
对于每组测试样例,如果这n个字符串顺序重排之后可以成语接龙,输出“Yes”,否则输出“No”。每个测试样例占一行。
Sample Input
3
5
Abcabc
Abc
Abca
Abc
A
2
ABAC
ACB
2
ACDB
ACB
Sample Output
Yes No No
Hint
第一组样例的成语接龙顺序可以为:A、Abc、Abc、Abca、Abcabc。
思路:
如果这些字符串可以成语接龙,那么接龙后的字符串满足: 前面的字符串的必定是后面字符串的子串,且前面字符串的长度小于等于后面的字符串
如果字符串长度相同的话,那么这两个字符串必须一样。
So,怎么做,
把字符串按长度从小到大排个序,遍历每个字符串,每个字符串只要满足这个字符串是后面字符串的子串即可(除最后一个)
代码:
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<string>
#include<algorithm>
#include<set>
using namespace std;
const int maxn=110;
string strArr[maxn];
int Solve(int index,int n)//判断下标为index是否为数组中其中一个字串
{
for(int i=0;i<n;++i)
{
if(i==index)
continue;
if(~strArr[i].find(strArr[index]))
return 1;
}
return 0;
}
bool cmp(string a,string b)
{
return a.length()<b.length();
}
int main()
{
int t;
int n,flag;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(int i=0;i<n;++i)
{
cin>>strArr[i];
}
sort(strArr,strArr+n,cmp);
flag=1;
for(int i=0;i<n-1;++i)//这个字符串必须后面字符串的字串
{
if(~strArr[i+1].find(strArr[i]))//不等于-1
continue;
flag=0;
}
if(flag)
printf("Yes
");
else
printf("No
");
}
}
如果还不太清楚的话
假设成语接龙后的字符串已经排列完成,前面字符串必定是后面字符串的子串。
*所有可以满足成语接龙的字符串都满足这样的情况0
*不满足就肯定不能进行成语接龙!