******************************************************************************************************************
题解:
给你n个字符串(全小写),让你按照输入的顺序来个字母表排列,(就是改变字母表的某些字母位置,使得你的输入是按照新的字典序)
如果前一个是后一个的子串,那么前一个一定小于后一个所以可以跳过。反之,如果后一个是前一个的子串,无论字典序怎么改都无法成立就输出"Impossible"。
新的字典序就是按照2个字符串的不同首字母,构建的有向图。
在使用拓扑排序就可以了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <string> 6 #include <vector> 7 #include <map> 8 #include <set> 9 #include <queue> 10 #include <sstream> 11 #include <algorithm> 12 using namespace std; 13 #define pb push_back 14 #define mp make_pair 15 #define mset(a, b) memset((a), (b), sizeof(a)) 16 typedef long long LL; 17 const int inf = 0x3f3f3f3f; 18 const int maxn = 100+10; 19 string s[maxn]; 20 int gap[30][30]; 21 int c[30], topo[30], t; 22 bool dfs(int u) 23 { 24 c[u] = -1; 25 for(int v = 0; v<26; v++) if(gap[u][v]){ 26 if(c[v] < 0 ) return false; 27 else if(!c[v] && !dfs(v)) return false; 28 } 29 c[u] = 1; topo[--t] = u; 30 return true; 31 } 32 bool toposort() 33 { 34 t = 26; 35 mset(c, 0); 36 for(int i=0;i<26;i++) if(!c[i]) 37 if(!dfs(i)) return false; 38 return true; 39 } 40 int main() 41 { 42 int n; 43 cin >> n; 44 for(int i=0;i<n;i++) cin >> s[i]; 45 for(int i=0;i<n-1;i++){ 46 int len1 = s[i].size(); 47 int len2 = s[i+1].size(); 48 int p = 0; 49 while(p<len1 && p<len2 && s[i][p]==s[i+1][p]) p++; 50 if(p == len1 && len1 < len2) continue; 51 if(p == len2 && len2 < len1) {cout<<"Impossible"<<endl;return 0;} 52 if(gap[s[i][p]-'a'][s[i+1][p] -'a'] == 1) continue; 53 gap[s[i][p]-'a'][s[i+1][p]-'a']=1; 54 } 55 if(toposort()){ 56 for(int i=0;i<26;i++) 57 printf("%c", topo[i]+'a'); 58 } 59 else 60 cout <<"Impossible"<< endl; 61 return 0; 62 }
来源:https://www.cnblogs.com/denghaiquan/p/6668473.html