链接:点击打开链接
题意:给出n个字符串按照一定的字典序排列,要求输出字典序的可能
代码:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
int N,M,k,cnt;
int head[105],indegree[105];
int que[105];
struct node{
int to,next;
}G[100005];
void addedge(int u,int v){
G[cnt].to=v;
G[cnt].next=head[u];
head[u]=cnt++;
}
int topo(){
int i,j;
for(i=1;i<=26;i++)
if(indegree[i]==0)
que[k++]=i;
for(i=0;i<k;i++){
for(j=head[que[i]];j!=-1;j=G[j].next){
indegree[G[j].to]--;
if(indegree[G[j].to]==0)
que[k++]=G[j].to;
}
}
} //拓扑排序
char s[105][105];
int cmp[50][50];
int main(){
int i,j,u,v,tmp,ans,len,sign;
while(cin>>N){
k=ans=cnt=0;
memset(cmp,0,sizeof(cmp));
memset(head,-1,sizeof(head));
memset(indegree,0,sizeof(indegree));
for(i=0;i<N;i++)
scanf("%s",s[i]);
for(i=0;i<N-1;i++){
sign=0;
len=min(strlen(s[i]),strlen(s[i+1]));
for(j=0;j<len;j++){
if(cmp[s[i][j]-'a'+1][s[i+1][j]-'a'+1]==1){
sign=1;
break;
} //判断之前是否出现过
if(s[i][j]!=s[i+1][j]){
addedge(s[i][j]-'a'+1,s[i+1][j]-'a'+1);
indegree[s[i+1][j]-'a'+1]++;
cmp[s[i][j]-'a'+1][s[i+1][j]-'a'+1]=1;
sign=1;
break;
} //有一个不相等则直接连边
}
if(sign==0&&strlen(s[i])>strlen(s[i+1])){
ans=1; //如果前缀相等当时前面的长度长则直接输出Impossible
break;
}
}
if(ans==1){
puts("Impossible");
continue;
}
topo();
if(k!=26) //判断是否有环
puts("Impossible");
else{
for(i=0;i<k;i++)
printf("%c",que[i]+'a'-1);
printf("\n");
}
}
return 0;
}