subsequence 2
题意:每次给出两个字母 和 只有这两个字母的原字符串的子序列,最后让你输出原字符串。
思路:先将字符转换为hash值,然后再转换成图,就是一个拓扑排序了,然后满足不了的情况有两种,一个是构造不了给出的n字符串大小,还有就是字母去重后多了。
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<string> #include<iostream> #include<queue> using namespace std; int n,m; char s[400100]; vector<int>G[400100]; int du[400010]; string ans=""; int num[26]; bool topo() { queue<int> q; for(int i=0;i<26;i++) { //printf("%d ",du[i*10000+1]); if(num[i]>0&&du[i*10000+1]==0) { q.push(i*10000+1); } } // printf("\n"); while(!q.empty()) { int u=q.front(); q.pop(); ans+=((u-1)/10000+'a'); for(int i=0;i<G[u].size();i++) { if(--du[G[u][i]]==0) q.push(G[u][i]); } } // cout<<ans<<endl; return n==ans.size(); } int main() { scanf("%d%d",&n,&m); int M; memset(num,-1,sizeof(num)); M=(m-1)*m/2; while(M--) { char a,b; char w[3]; int len; scanf("%s",w); scanf("%d",&len); if(len==0) continue; scanf("%s",s); int suma=0; int sumb=0; int pre=-1; a=w[0]; b=w[1]; for(int i=0;i<len;i++) { int id=0; if(s[i]==a) { suma++; id=(s[i]-'a')*10000+suma; } if(s[i]==b) { sumb++; id=(s[i]-'a')*10000+sumb; } if(pre!=-1) { // printf("id:%d\n",id); du[id]++; G[pre].push_back(id); } pre=id; } if(num[a-'a']==-1) num[a-'a']=suma; if(num[b-'a']==-1) num[b-'a']=sumb; } int sum=0; for(int i=0;i<m;i++) { sum+=num[i]; } if(sum!=n){ printf("-1\n"); // printf("000"); } else{ if(topo()) { cout<<ans<<endl; } else printf("-1\n"); } }