R290 DIV2 C. Fox And Names
Chieh
posted @ 2015年2月03日 17:19
in codeforces
, 246 阅读
飞机票:http://codeforces.com/problemset/problem/510/C
题意:就是给你n个字符串,按字典序从上到下递增,判断字典序是否正确,正确输出任意一个可行的方案,不行则impossible
分析:刚开始看对题,但是自己想法错误,大晚上想法不行啊后来还是想回来了,我的想法是分治法。
假设n个字符串,第i个到第j个(i<j)的第一个字符都是一样的,则它们还得比较第二个字符。。。。第k个字符,直到不一样为止。
当不一样时我们就可以加边了,假设不一样的字符是第k个,则字符串i的第k个字符<字符串j的第k个字符,加单向边,一直到最后,然后用floyd判断有无环,有环则impossible,没环则输出可行方案可以方案怎么输出,我是枚举的,因为数量不大,假设当前的字符是i,则判断有没有j可以到i的,如果j输出过了,则跳过,如果没有,则可以证明i是当前最小的,把i输出来,然后标记i就行了。。。这里还有个地方,就是字符串长度的问题,假设到比较第k个字符串了,来个标记,如果从i到p是空的,p+1是不空的,则改变标记,这样后面如果有空的,就是impossible,直接返回~
PS:大晚上明明返回标记了,后面忘了判断输出了,fst了改一下就AC了
/* Author:Chieh Because of You */ #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <map> #include <vector> #include <stack> #define LL long long using namespace std; map<char,int> M; map<int,char> M1; const int maxn=30; int ai[maxn][maxn]; char ch[123][123]; int n; int len; void init() { len=0; for(int i=1; i<=n; i++) { scanf("%s",ch[i]+1); int q=strlen(ch[i]+1); len=max(len,q); } } bool flag; int st; void DFS(int now,int l,int r) { if(!flag)return ; char before='A'; int ks=0; int os=-1; for(int i=l; i<=r; i++) { int q=strlen(ch[i]+1); char p=ch[i][now]; if(now>q&&os==-1)continue; os=1; if(now>q) { flag=0; return; } if(before=='A') { ks=l; before=ch[i][now]; } else { if(before==p) { continue; } else { if(M[before]==0) { M[before]=st; M1[st]=before; st++; } if(M[p]==0) { M[p]=st; M1[st]=p; st++; } int u=M[before]; int v=M[p]; before=p; ai[u][v]=1; if(i-1==ks) { ks=i; continue; } else { DFS(now+1,ks,i-1); } ks=i; } } } if(r==ks)return; else if(ks==0)return; DFS(now+1,ks,r); } bool vis[maxn]; void play() { memset(ai,0,sizeof(ai)); memset(vis,0,sizeof(vis)); flag=1; M.clear(); M1.clear(); st=1; DFS(1,1,n); if(!flag) { printf("Impossible\n"); return; } for(int k=1; k<=29; k++) { for(int i=1; i<=29; i++) { for(int j=1; j<=29; j++) { if(ai[i][k]&&ai[k][j]) { ai[i][j]=1; } } } } for(int i=1; i<=29; i++) { for(int j=1; j<=29; j++) { if(ai[i][j]&&ai[j][i]) { printf("Impossible\n"); return; } } } for(char i='a'; i<='z'; i++) { if(M[i]==0)printf("%c",i); } while(1) { bool ok=0; for(int i=1; i<=29; i++) { if(vis[i])continue; if(M1[i]!=0) { bool flag=1; for(int j=1; j<=29; j++) { if(vis[j])continue; if(M1[j]==0)continue; if(ai[j][i]) { flag=0; break; } } if(flag) { printf("%c",M1[i]); vis[i]=1; ok=1; } } } if(!ok)break; } printf("\n"); } int main() { while(scanf("%d",&n)!=EOF) { init(); play(); } // cout << "Hello world!" << endl; return 0; }