题目链接: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 "); else { printf("YES "); for (int i = 0; i < n; i++) cout << str[i] << endl; } } return 0; }
2018-06-14