1396 病毒(virus)

#include <bits/stdc++.h>
using namespace std;
int n,tot;
int f[30],G[30][30],v[30],res[30],h[30];
//f记录入度,G记录前后,v记录是否入队,res中转,h记录对应顺序
string s[50010];
stack<int> r;
int main()
{
    memset(f,0x3f,sizeof(f));
    cin>>n;
    for(int i=1;i<=n;i++) cin>>s[i];
    for(int i=1;i<n;i++){
        if(s[i]==s[i+1]) //完全相同,下一个
            continue;
        if(s[i+1].find(s[i])==0) //后一个包含前一个,没有比较的意义
            continue;
        if(s[i].find(s[i+1])==0){//前一个包含后一个,字典错误(与上一个相反)
            puts("0"); 
            return 0; 
        }
        int x=0;
        while(s[i][x]==s[i+1][x]) //寻找不同字母
            x++;
        int a=s[i][x]-'a'+1,b=s[i+1][x]-'a'+1;
        if(G[b][a]){ //这里a在b前,而之前b在a前,前后矛盾,字典错误,结束
            puts("0"); 
            return 0; 
        }
        G[a][b]=1;//存储
        if(!v[a]) v[a]=1,f[a]=0;
        if(!v[b]) v[b]=1,f[b]=1;
        else f[b]++;//入度加一
    }
    memset(v,0,sizeof(v));
    for(int i=1;i<30;i++) 
        if(!f[i]) 
            r.push(i),v[i]=1;
    while(r.size()) {//拓扑排序
        int x=r.top(); r.pop();
        res[++tot]=x;//记录当前
        for(int i=1;i<30;i++) {
            if(G[x][i]) f[i]--;//入度减一
            if(!f[i]&&!v[i]) 
                r.push(i),v[i]=1;
        }
    }
    for(int i=1;i<=tot;i++) 
        h[res[i]]=i;
    string que,ans; //que是被感染的字符串,ans是答案
    cin>>que;
    for(int i=0;i<que.length();i++) {
        if(!h[que[i]-'a'+1]){//字典不完整,找不到对应字符
            puts("0"); 
            return 0;
        }
        ans+=(char)(h[que[i]-'a'+1]+'a'-1);//记录答案
    }
    cout<<ans<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值