成语接龙(字符串,思路,按长度排序)

成语接龙

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

*不满足就肯定不能进行成语接龙!

原文地址:https://www.cnblogs.com/dchnzlh/p/10427307.html