zoukankan      html  css  js  c++  java
  • codeforces Gym 100286J Javanese Cryptoanalysis (二染色)

    每一单词相邻两个字母,不能同时为元音或者辅音。。。

    各种姿势都可以过:7个for,dp,黑白染色,dfs,并查集。。。。

    最主要的思路就是相邻字母连边,把元音和辅音看成两个集合,那么有连边的两个字母一定不能出现在同一个集合中,于是想到了二分图判断的二染色。

    比较坑的是,必须要出现5个元音字母

    见识到了str = str + str2有多慢

    #include<bits/stdc++.h>
    using namespace std;
    
    #define PB push_back
    int color[26];
    
    int G[26][26];
    const int maxn  = 1e5+5;
    char s[maxn];
    bool vis[26];
    
    char mp[26];
    
    bool bipartite(int u)
    {
        for(int v = 0; v < 26; v++) if(G[u][v]) {
            if(color[v] == color[u]) return false;
            if(!color[v]){
                color[v] = 3 - color[u];
                if(!bipartite(v)) return false;
            }
        }
        return true;
    }
    
    
    char tab[5] = {'A','E','I','O','U'};
    int tsz = 0,tsz2 = 0;
    char tab2[21]  = {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Y','Z'};
    
    vector<string> word;
    vector<int> bcc[26][2];
    int bcnt;
    
    bool dfs(int d,int cur,int s)
    {
        if(d == bcnt){
            if(cur == 5){
                for(int i = 0; i < bcnt; i++){
                   vector<int> &v = bcc[i][(s>>i)&1];
                   for(int j = 0; j < v.size(); j++){
                        mp[v[j]] = tab[tsz++];
                    }
                }
                return true;
            }
            return false;
        }
        if(dfs(d+1,cur+bcc[d][0].size(),s)||dfs(d+1,cur+bcc[d][1].size(),s|(1<<d))) return true;
        return false;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        freopen("javanese.in","r",stdin);
        freopen("javanese.out","w",stdout);
        while(~scanf("%s",s)){
            word.PB(s);
            for(int i = 1; s[i]; i++){
                int u = s[i] - 'A', v = s[i-1] - 'A';
                G[u][v] =  G[v][u] = 1;
            }
        }
    
        for(int i = 0; i < 26; i++)if(!color[i]){
            color[i] = 1;
            if(!bipartite(i)) { puts("impossible"); return 0; }
            for(int i = 0; i < 26; i++) if(color[i]&&!vis[i]) {
                vis[i] = true;
                bcc[bcnt][color[i]-1].PB(i);
            }
            bcnt++;
        }
    
        if(!dfs(0,0,0)) { puts("impossible"); }
        else {
            for(int i = 0; i < 26; i++) if(!mp[i]) mp[i] = tab2[tsz2++];
            for(int j = 0; j < word.size(); j++){
                if(j) putchar(' ');
                string & str = word[j];
                for(int i = 0; i < str.size(); i++){
                    if('A'<=str[i]&&str[i]<='Z')
                       putchar(mp[str[i]-'A']);
                    else putchar(str[i]);
                }
            }
            putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    python 读写文件
    python之创建文件写入内容
    python之生成随机密码
    python实例七
    python 实例六
    python 实例四
    python实例二
    python实例一
    【BZOJ】1610: [Usaco2008 Feb]Line连线游戏
    【BZOJ】1602:[Usaco2008 Oct]牧场行走
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4713981.html
Copyright © 2011-2022 走看看