• Codeforces510 C. Fox And Names


    Codeforces题号:#510C

    出处: Codeforces

    主要算法:判环+拓扑

    难度:4.2

    思路分析:

           要是把这道题联系到图上就很容易想了。

      如何建图?由于最后要求名字满足字典序,所以不妨以字母为节点,然后按照题意的顺序从小的到大的连边。建图了又什么用?如果图存在环,那么也就意味着矛盾了——因为这比自己小的节点比自己大。因此是否存在一个合法的字典序的判断依据就是建的图是否存在环。

      第二步,如何输出任意一个方案?这很简单,由于有可能有的字母根本没有参与建图,所以这些字母就不需要管了。对于在图里的字母,入度为0的点就是已知的应当最小的点——所以我们进行一次拓扑排序来得到序列。最后和其它字母拼合起来就好了。

    代码注意点:

      注意有两个相同前缀的字符串时,如果前面的那个字符串比后面的还要长,那么一定不满足,直接输出impossible就好了。因为无论字典序如何,都不可能满足前面的字典序比后面的小。

    Code

    /** This Program is written by QiXingZhi **/
    #include <cstdio>
    #include <queue>
    #include <iostream>
    #include <string>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #define  r  read()
    #define  Max(a,b)  (((a)>(b)) ? (a) : (b))
    #define  Min(a,b)  (((a)<(b)) ? (a) : (b))
    using namespace std;
    typedef long long ll;
    const int N = 1010;
    const int INF = 1061109567;
    inline int read(){
        int x = 0; int w = 1; register int c = getchar();
        while(c ^ '-' && (c < '0' || c > '9')) c = getchar();
        if(c == '-') w = -1, c = getchar();
        while(c >= '0' && c <= '9') x = (x << 3) +(x << 1) + c - '0', c = getchar();
        return x * w;
    }
    string s[N];
    queue <int> q;
    vector <int> G[3000];
    bool exist[N],vis[N],b[N],hh[N];
    int rd[N],Q[N],ans_topo[N];
    int n,len1,len2,flg,_cur,t,topo_num;
    inline void AddEdge(int u, int v){
        exist[u] = 1;
        exist[v] = 1;
        G[u].push_back(v);
        ++rd[v];
    }
    inline void ThrowOut(){
        printf("Impossible");
        exit(0);
    }
    inline bool BFS(int x){
        while(!q.empty()) q.pop();
        q.push(x);
        int cur,sz,to;
        while(!q.empty()){
            cur = q.front();
            q.pop();
            if(cur == _cur){
                if(flg == -1){
                    ++flg;
                }
                else if(flg == 0){
                    return 1;
                }
            }
            if(vis[cur]) continue;
            vis[cur] = 1;
            sz = G[cur].size();
            for(int i = 0; i < sz; ++i){
                to = G[cur][i];
                q.push(to);
            }
        }
        return 0;
    }
    inline bool Check_Circle(){
        for(int i = 'a'; i <= 'z'; ++i){
            memset(vis,0,sizeof(vis));
            if(exist[i]){
                _cur = i;
                flg = -1;
                if(BFS(_cur)) return 1;
            }
        }
        return 0;
    }
    int main(){
    //    freopen(".in","r",stdin);
        cin >> n;
        for(int i = 1; i <= n; ++i){
            cin >> s[i];
        }
        for(int i = 2; i <= n; ++i){
            len1 = s[i-1].size();
            len2 = s[i].size();
            flg = 0;
            for(int j = 0; j < len2; ++j){
                if(j >= len1){
                    flg = 1;
                    break;
                }
                if(s[i-1][j] != s[i][j]){
                    flg = 1;
                    AddEdge(s[i-1][j],s[i][j]);
                    break;
                }
            }
            if(flg == 0 && len1 > len2){
                ThrowOut();
            }
        }
        if(Check_Circle() == 1){
            ThrowOut();
        }
        int flg=0,sz;
        for(;;){
            flg = 0, t = 0;
            for(int i = 'a'; i <= 'z'; ++i){
                if(rd[i] == 0 && !b[i] && exist[i]){
                    flg = 1;
                    b[i] = 1;
                    Q[++t] = i;
                }  
            }
            if(!flg) break;
            for(int i = 1; i <= t; ++i){
                int cur = Q[i];
                ans_topo[++topo_num] = cur;
                hh[cur] = 1;
                sz = G[cur].size();
                for(int j = 0; j < sz; ++j){
                    --rd[G[cur][j]];
                }
            }
        }
        for(int i = 1; i <= topo_num; ++i){
            printf("%c",ans_topo[i]);
        }
        for(int i = 'a'; i <= 'z'; ++i){
            if(!hh[i]){
                printf("%c",i);
            }
        }
        return 0;
    }
  • 相关阅读:
    [Swift]LeetCode1035.不相交的线 | Uncrossed Lines
    [Swift]LeetCode1034.边框着色 | Coloring A Border
    [Swift]LeetCode1033. 移动石子直到连续 | Moving Stones Until Consecutive
    [Swift]美人征婚问题
    [Swift]动态变化顶部状态栏(statusBar)的颜色
    [Swift-2019力扣杯春季决赛]4. 有效子数组的数目
    [Swift-2019力扣杯春季决赛]3. 最长重复子串
    [Swift-2019力扣杯春季决赛]2. 按字典序排列最小的等效字符串
    转 ORA-12638: 身份证明检索失败
    转 构建镜像
  • 原文地址:https://www.cnblogs.com/qixingzhi/p/9299446.html
Copyright © 2020-2023  润新知