Codeforces Round #486 (Div. 3) B Substrings Sort

题目链接:https://vjudge.net/contest/234309#problem/C

题目大意:

给你n个字符串,每个字符串都是有小写字母组成的。重新给这些字符串 
排序按照以下规则:每个字符串的前面都是它的子串 
如果在b中选择连续的字母可以组成a,则称a是b的子串。比如字符串“for” 
是“codeforces”的子串,“for”是“therefore”的子串,但是没有子串“four”“fofo”和“rof”。 
输入: 
第一行是一个整数n(字符串的数量) 
下面的n行是给你的字符串。字符串的长度为1到100。每个字符串 
由小写字母组成。 
一些字符串可能是相同的。 
输出: 
如果重新排序后可以不可能满足要求的序列就输出“NO”(没有引号)。 
否则输出“YES”和n行要求的字符串的序列。 
提示:在第二个样例中,你不可以重新排序“abab”使它为“abacaba”的子串。

#include <string>
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <map>
using namespace std;

bool cmpp(string a, string b)                //注意要按题意将字符串排序
{
    if (a.length() == b.length())
        return a < b;
    return a.length() < b.length();
}

int main()
{
    int n;
    while (scanf("%d", &n) != EOF)
    {
        string str[110];
        for (int i = 0; i < n; i++)
            cin >> str[i];
        sort(str, str + n,cmpp);
        map<string, int>mapp;
        int flag = 0;
        for (int i = 1; i < n&&!flag; i++)            //判断第i个字符串是否符合题意     
        {
            mapp.clear();        //记住每次要清空map
            for (int j = 0; j < i&&!flag; j++)        //遍历前i-1个字符串是否为第i个字符串的字串
            {
                int len = str[j].length();             //第j个字符串的长度
                for (int k = 0; k <= str[i].length() - len; k++)
                {
                    mapp[str[i].substr(k, len)]++;         //标记第i个string中起点为0~str[i].length() - len的,长度为len的string
                }
                if (mapp[str[j]] == 0)flag = 1;           //如果str[j]未被标记,这说明str[j]不为str[i]的字串
            }
        }
        if (flag)printf("NO\n");
        else
        {
            printf("YES\n");
            for (int i = 0; i < n; i++)
                cout << str[i] << endl;
        }
    }
    return 0;
}

2018-06-14

猜你喜欢

转载自www.cnblogs.com/00isok/p/9185557.html