codeforces-510C-Fox And Names【DFS】

codeforces-510C-Fox And Names【DFS】

                time limit per test2 seconds    memory limit per test256 megabytes

Fox Ciel is going to publish a paper on FOCS (Foxes Operated Computer Systems, pronounce: “Fox”). She heard a rumor: the authors list on the paper is always sorted in the lexicographical order.

After checking some examples, she found out that sometimes it wasn’t true. On some papers authors’ names weren’t sorted in lexicographical order in normal sense. But it was always true that after some modification of the order of letters in alphabet, the order of authors becomes lexicographical!

She wants to know, if there exists an order of letters in Latin alphabet such that the names on the paper she is submitting are following in the lexicographical order. If so, you should find out any such order.

Lexicographical order is defined in following way. When we compare s and t, first we find the leftmost position with differing characters: si ≠ ti. If there is no such position (i. e. s is a prefix of t or vice versa) the shortest string is less. Otherwise, we compare characters si and ti according to their order in alphabet.

Input
The first line contains an integer n (1 ≤ n ≤ 100): number of names.

Each of the following n lines contain one string namei (1 ≤ |namei| ≤ 100), the i-th name. Each name contains only lowercase Latin letters. All names are different.

Output
If there exists such order of letters that the given names are sorted lexicographically, output any such order as a permutation of characters ‘a’–’z’ (i. e. first output the first letter of the modified alphabet, then the second, and so on).

Otherwise output a single word “Impossible” (without quotes).

input
3
rivest
shamir
adleman
output
bcdefghijklmnopqrsatuvwxyz

input
10
tourist
petr
wjmzbmr
yeputons
vepifanov
scottwu
oooooooooooooooo
subscriber
rowdark
tankengineer
output
Impossible

input
10
petr
egor
endagorion
feferivan
ilovetanyaromanova
kostka
dmitriyh
maratsnowbear
bredorjaguarturnik
cgyforever
output
aghjlnopefikdmbcqrstuvwxyz

input
7
car
care
careful
carefully
becarefuldontforgetsomething
otherwiseyouwillbehacked
goodluck
output
acbdefhijklmnogpqrstuvwxyz

题目链接:cf-510C

题目大意:给出n个字符串按某种字典序排列,求该字典序。

题目思路:DFS

以下是代码:

#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
using namespace std;
string s[100];
int vis[100];
int pre[100];
vector <int> g[30];
int last[100];
int ans = 1;
int size = 0;
void dfs(int p)
{   
    vis[p] = 1;
    pre[p] = 1;
    for (int i = 0; i < g[p].size(); i++)  //寻找是否存在比这个字母小的字母
    {
        if (!vis[g[p][i]]) dfs(g[p][i]);
        else if (pre[g[p][i]]) ans = 0;  //如果A之前出现过且大于B这个字母,但是在比B小的数组中又找到A这个字母,出现矛盾,不符合字典序。
    }
    pre[p] = 0;
    last[size++] = p;    //记录答案

}
int main(){
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)  cin >> s[i];
    for (int i = 1; i < n; i++)
    {
        string m1 = s[i - 1];
        string m2 = s[i];
        int j;
        for (j = 0; j < m1.size() && j < m2.size() && m1[j] == m2[j]; j++);  //找到第一个不同的字母
        if (j < m1.size() && j < m2.size())   
        {
            g[m1[j] - 'a'].push_back(m2[j] - 'a');  //m2[j]排在m1[j]的后面
        }
        else if (m1.size() > m2.size())  ans = 0;//如果两个串前缀都相同但是m2长度更长,则不可能存在该字典序
    }
    for (int i = 0; i < 26; i++) if (!vis[i]) dfs(i);   //dfs每个字母
    if (ans)
    {
        for (int i = size-1; i >= 0; i--)//输出需要注意
        {
            printf("%c",last[i] + 'a');
        }
    }
    else puts("Impossible");
    return 0;
}

你可能感兴趣的:(DFS)