CF - Fox And Names
题意:给你n个字符串,这些字符串是按照某种字母规律排序的,判断是否存在这种规律,如果存在,要求找出字母排序的规律。
分析:拓扑排序,具体看代码注解。
题解:
#include <bits/stdc++.h> using namespace std; int n; string s[105]; char ans[30];//存储答案 bool vis[30][30];//是否有连边 int in[30];//入度 void topsort() { //找第i个答案 for(int i=0;i<26;i++) { bool flag=0;//是否找到一个入度为0的点 int tmp;//存储当前需要计入答案的字母 for(int j=0;j<26;j++) { if(in[j]==0) { tmp=j; flag=1; break; } } //找不到说明存在环 if(!flag) { cout<<"Impossible"; return; } //找到后,存入答案,去掉这个点 in[tmp]=-1; char now=(char)(tmp+'a'); ans[i]=now; for(int j=0;j<26;j++) { if(vis[tmp][j]) in[j]--; } } cout<<ans; } int main() { memset(in,0,sizeof in); memset(vis,0,sizeof vis); cin>>n; for(int i=1;i<=n;i++) { cin>>s[i]; } //记录连边和入度 bool flag1=1;//当后一个是前一个的前缀子串,必定不符合要求 for(int i=1;i<n;i++) { int j=i+1; int len1=s[i].length(); int len2=s[j].length(); bool flag2=0;//判断是否有不同 //逐位比较 for(int k=0;k<min(len1,len2);k++) { if(s[i][k]!=s[j][k]) { flag2=1; if(!vis[s[i][k]-'a'][s[j][k]-'a'])//没连过边 { vis[s[i][k]-'a'][s[j][k]-'a']=1; in[s[j][k]-'a']++;//入度+1 } break;//两个字符不同之后就不需要再判断了 } } //后面的是前面的子串,不合法 if(!flag2&&len1>len2) { flag1=0; break; } } if(!flag1) { cout<<"Impossible"; } else topsort(); return 0; }

浙公网安备 33010602011771号