2019牛客暑期多校训练营(第五场)H.subsequence 2(拓扑排序)

链接:https://ac.nowcoder.com/acm/contest/885/H
来源:牛客网
 

题目描述

There is a hidden string of length n composed of the first m lowercase English letters. For any two different English letters, we will tell you a subsequence of the hidden string constructed by removing all other letters from the hidden string.

For example, if the hidden string is "apple" and the chosen letters are 'e' and 'p', the resulting subsequence would be "ppe"; if the chosen letters are 'a' and 'x', the resulting subsequence would be "a".

Now, please recover the hidden string. Output -1 if there are no possible hidden string. Output any one if there are multiple possible hidden strings.

输入描述:

The first line contains two integers n and m.

Following are m⋅(m−1)/2m \cdot (m-1)/2m⋅(m−1)/2 groups of two lines. The first line in each group contains a two-letter string composed of c1, c2, and an integer LEN. The second line contains a string composed of letters c1, c2 with length LEN, indicates the resulting subsequence by removing all other letters except c1 and c2 from the hidden string.

* 1≤n≤1041 \le n \le 10^41≤n≤104

* 2≤m≤102 \le m \le 102≤m≤10

* 0≤LEN≤n0 \le LEN \le n0≤LEN≤n

* all unordered pairs of letters in first m small English letters will occur exactly once.

输出描述:

If there is at least one possible hidden string, please output any. Otherwise, output -1.

示例1

输入

复制

3 3
ab 2
ab
bc 2
bc
ca 2
ac

输出

复制

abc

说明

First group tells us that there is one 'a' and one 'b' where 'a' is before 'b', the second group tells us there is one 'b' and one 'c' where 'b' is before 'c'. So the only possible answer is "abc" which satisfies the last group as well.

示例2

输入

复制

3 3
cb 3
bbc
ca 2
ac
ab 3
abb

输出

复制

-1

示例3

输入

复制

4 3
ac 4
cccc
ba 0

cb 4
cccc

输出

复制

cccc

题目大意:现在有一个隐藏的字符串,字符串长度为N,字符串是由M个字符组成的,M个字符也就是从a到a+m这个区间内的,有一个操作是这样的,挑出两个字符,然后他会把所有的除了这两个字符的其他字符在这个字符串中删掉,会给你所有可能的两个字符的这种操作。

思路:觉得这个题目最重要的也就是把那些字符给编上号,不然如果出现了很多个相同的字符是很麻烦的,

这里每一个字符都保存一下他的位数和相对添加进来的位置就好了,

拓扑排序建边的时候其实只需要建立相邻的边就好了,

代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
const int maxn=1000005;
string str;
int num[maxn],vis[maxn];
int degree[maxn],d[30];
vector<int >G[maxn];
vector<int >v[30];
vector<int >ans;
int n,m;
int main()
{
    scanf("%d%d",&n,&m);
    m=m*(m-1)/2;
    int tot=0;
    while(m--)
    {
        int t;
        cin>>str>>t;
        if(t) cin>>str;
        else getchar();
        int pre=-1;
        memset(d,0,sizeof(d));
        for(int i=0;i<t;i++)
        {
            int id=str[i]-'a'+1;
            d[id]++;
            if(v[id].size()<d[id])
            {
                ++tot;
                v[id].push_back(tot);
                num[tot]=id;
            }
            if(pre!=-1)
            {
                G[pre].push_back(v[id][d[id]-1]);
                degree[v[id][d[id]-1]]++;
            }
            pre=v[id][d[id]-1];
        }
    }
    queue<int >Q;
    for(int i=1;i<=tot;i++)
    {
        if(degree[i]==0)Q.push(i);
    }
    while(!Q.empty())
    {
        int u=Q.front();Q.pop();
        ans.push_back(u);
        for(int i=0;i<G[u].size();i++)
        {
            int v=G[u][i];
            degree[v]--;
            if(degree[v]==0)
            {
                Q.push(v);
            }
        }
         G[u].clear();
    }
    if(ans.size()!=n) printf("-1\n");
    else
    {
        for(int i=0;i<ans.size();i++)
            printf("%c",num[ans[i]]+'a'-1);
        printf("\n");
    }
}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值