【Codeforces Round #290 (Div. 2)-C. Fox And Names】 思维题+拓扑排序

Codeforces Round #290 (Div. 2)-C. Fox And Names

题意

给 你 n 个 字 符 串 , 让 你 设 计 一 种 字 典 序 使 这 n 个 字 符 串 满 足 字 典 序 从 小 到 大 给你n个字符串,让你设计一种字典序使这n个字符串满足字典序从小到大 n使n
如 果 不 能 设 计 输 出 i m p o s s i b l e 如果不能设计输出impossible impossible
n &lt; = 100 ; ∣ s ∣ &lt; = 100 n&lt;=100;|s|&lt;=100 n<=100;s<=100

做法

n 2 扫 描 所 有 字 符 串 , 对 使 每 两 个 串 字 典 序 不 同 的 主 要 字 母 建 图 ( 也 就 是 第 一 个 不 同 的 字 母 ) n^2扫描所有字符串,对使每两个串字典序不同的主要字母建图(也就是第一个不同的字母) n2使
建 图 之 后 跑 一 下 拓 扑 排 序 , 如 果 满 足 拓 扑 序 也 就 是 没 有 环 出 现 , 那 么 直 接 输 出 拓 扑 序 即 可 。 建图之后跑一下拓扑排序,如果满足拓扑序也就是没有环出现,那么直接输出拓扑序即可。

坑点

判 一 下 有 没 有 一 短 一 长 前 缀 完 全 相 同 , 但 是 长 度 不 同 字 典 序 错 误 的 情 况 。 判一下有没有一短一长前缀完全相同,但是长度不同字典序错误的情况。
比 如 A A A , A A , 但 是 A A A 出 现 在 前 面 , 这 种 情 况 也 应 该 输 出 i m p o s s i b l e 比如AAA,AA,但是AAA出现在前面,这种情况也应该输出impossible AAAAAAAAimpossible

代码

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
const int maxn = 105;
char str[maxn][maxn];
vector<int> v[maxn];
int ind[maxn], que[maxn],m;//ind数组要清空
bool topsort()//还要特判自环
{
    int qt = 0;
    for(int i = 0;i<26; ++i)
    {
        if(ind[i] == 0) que[qt++] = i;
    }
    for(int i = 0; i < qt; ++i)
    {
        int u = que[i];
        for(int j = 0; j < v[u].size(); ++j)
        {
            if(--ind[v[u][j]] == 0) que[qt++] = v[u][j];
        }
    }
    return qt == 26;
}
int main()
{
    int n;
    int flag=0;//存储是否有前缀完全相同一长一短不满足字典序的情况
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%s",str[i]);
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            int ff=0;
            int len1=strlen(str[i]);
            int len2=strlen(str[j]);
            for(int pos1=0,pos2=0;pos1<len1&&pos2<len2;pos1++,pos2++)
            {
                if(str[i][pos1]!=str[j][pos2])
                {
                    v[str[i][pos1]-'a'].push_back(str[j][pos2]-'a');
                    ind[str[j][pos2]-'a']++;
                    ff=1;
                    break;
                }
            }
            if(ff==0&&len1>len2) flag=1;
        }
    }
    if(topsort()&&flag==0)
    {
        for(int i=0;i<26;i++) printf("%c",(char)que[i]+'a');
    }
    else
    {
        printf("Impossible\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值