1. 程式人生 > >【Codeforces Round #290 (Div. 2)-C. Fox And Names】 思維題+拓撲排序

【Codeforces Round #290 (Div. 2)-C. Fox And Names】 思維題+拓撲排序

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

題意

n

使
n 滿
給你n個字串,讓你設計一種字典序使這n個字串滿足字典序從小到大
i m p o s s i b l e 如果不能設計輸出impossible
n < = 100 ; s < = 100 n<=100;|s|<=100

做法

n 2 使 n^2掃描所有字串,對使每兩個串字典序不同的主要字母建圖(也就是第一個不同的字母)
滿 建圖之後跑一下拓撲排序,如果滿足拓撲序也就是沒有環出現,那麼直接輸出拓撲序即可。

坑點

判一下有沒有一短一長字首完全相同,但是長度不同字典序錯誤的情況。
A A A A A A A A i m p o s s i b l e 比如AAA,AA,但是AAA出現在前面,這種情況也應該輸出impossible

程式碼

#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;
}