题意:给n个字符串,问是否存在一个合法的字典,使得这些字符串是字典序递增的。
对相邻两个字符串的第一个不相等字符建边,拓扑排序即可。
注意边界判断。
#include <bits/stdc++.h>
using namespace std;
const int MAXN=505;
char str[MAXN][15];
int in[26];
bool used[26][26];
int main(){
int n, cnt;
queue<int> q;
while(cin>>n&&n){
memset(in,0,sizeof in);
memset(used,0,sizeof used);
bool flag=true;
for(int i=0; i<n; i++){
scanf("%s",str[i]);
int len=strlen(str[i]);
if(i&&flag){
for(int k=0; k<len; k++){
if(str[i][k]==str[i-1][k]){
continue;
}
if(!str[i-1][k]) goto ok;
int s1=str[i-1][k]-'a', s2=str[i][k]-'a';
if(used[s2][s1]) flag=false;
if(!used[s1][s2]){
used[s1][s2]=true;
in[s2]++;
}
goto ok;
}
if(str[i-1][len]) flag=false;
ok:;
}
}
if(!flag) goto failed;
while(!q.empty()) q.pop();
for(int i=0; i<26; i++){
if(in[i]==0){
q.push(i);
}
}
cnt=0;
while(!q.empty()){
int now=q.front(); q.pop();
for(int i=0; i<26; i++){
if(used[now][i]){
in[i]--;
if(in[i]==0){
q.push(i);
}
}
}
cnt++;
}
if(cnt!=26) goto failed;
puts("yes");
continue;
failed:;
puts("no");
}
return 0;
}