• 2013-2014 ACM ICPC Central European Regional Contest (CERC 13) K-Digraphs


    题意

    要求构造一个字符方阵。给定n对字符,每对字符表示这两个字符不能出现在方阵中,输出方案

    思路

    很容易想到两个字符间连一条有向边,构成一张有向图,遍历它的补图,若该补图有环,则输出这个环,注意环的长度若大于20要截取;若无环,则输出最长链。
    问题转化为给定一张有向图,找环,若无环,找最长链。做法是枚举起点dfs找最长链,在搜索过程中记录点的状态,当搜到点cur时,若cur到起点u有边,则找到环,此时cir记为1,便于回溯时剪枝。一开始用vector存储路径但是一直wa也搞不清问题在哪,仿照别人用的数组才过,可是看上去没差别啊

    代码

    #include<bits/stdc++.h>
    #define inf 0x3f3f3f3f
    #define ms(a) memset(a,0,sizeof(a))
    using namespace std;
    typedef long long ll;
    
    const int M = int(1e5) + 5;
    const int mod = int(1e9) + 7;
    
    int g[50][50];
    bool vis[30];
    // vector<int> path;
    // vector<int> tem;
    int path[M];
    int tem[M];
    int plen;
    bool cir;
    
    bool dfs(int u,int cur,int len){
        vis[cur]=1;
        if(cir==1){
            return true;
        }
        if(g[cur][u]==0 && vis[u]){
            cir=1;
            // tem.push_back(cur);
            // path=tem;
            plen=len;
            path[len]=cur;
            memcpy(path,tem,sizeof(path));
            return true;
        }
    
        bool flag=0;
        for(int i=0;i<26;i++){
            if(g[cur][i]==0 && !vis[i]){
                flag=1;
                // tem.push_back(i);
                tem[len]=i;
                if(dfs(u,i,len+1)){
                    return true;
                }
                vis[i]=0;
                // tem.pop_back();
            }
        }
        if(flag==0){
            // if(path.size()<tem.size()){
            //     path=tem;
            // }
            if(len>plen){
                memcpy(path,tem,sizeof(path));
                plen=len;
            }
        }
        return false;
    
    }
    int main(){
        int t;
        cin>>t;
        while(t--){
            // path.clear();
            // tem.clear();
            ms(path);
            ms(tem);
            cir=0;
            ms(g);
            plen=0;
            
            int n;
            cin>>n;
            while(n--){
                char a,b;
                cin>>a>>b;
                g[a-'a'][b-'a']=-1;
            }
    
            for(int i=0;i<26;i++){
                ms(vis);
                // tem.push_back(i);
                tem[0]=i;
                // vis[i]=1;
                // int t=0;
                // while(t<26 && g[i][t]==-1){
                //     t++;
                // }
                // if(t==26){
                //     continue;
                // }
                if(dfs(i,i,1)){
                    break;
                }
                // tem.clear();
            }
    
            
            // int len=path.size();
            if(cir==1){
                for(int i=0;i<20;i++){
                    for(int j=0;j<20;j++){
                        cout<<(char)(path[(j+i%plen)%plen]+'a');
                    }
                    cout<<endl;
                }
            }
            else{
                // len=max(len,39);
                int nn=plen + 1 >> 1;
                for(int i=0;i<nn;i++){
                    for(int j=0;j<nn;j++){
                        cout<<(char)(path[(j+i)]+'a');
                    }
                    cout<<endl;
                }
            }
        }
        return 0;
    }
    
  • 相关阅读:
    前端CSS部分简单整理
    前端HTML部分简单整理
    Top Android App使用的组件
    使用DialogFragment创建对话框总结
    Rails常用命令
    developer.android.com笔记
    Google Maps API v2 Demo Tutorial
    Android学习的一些问题
    Android学习过程
    Beginning Android 4 Programming Book学习
  • 原文地址:https://www.cnblogs.com/harutomimori/p/12912814.html
Copyright © 2020-2023  润新知