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");
    }
}

 

posted @ 2019-08-02 19:02  Ldler  Views(187)  Comments(0Edit  收藏  举报