zoukankan      html  css  js  c++  java
  • PAT-L3-球队“食物链”-dfs-状压-set

    题目分析:

    1. 一场双循环赛制的篮球赛,注意双循环,双循环!

    2. 共有n只球队,两两之间有胜有负有平局;

    3. 输入:

        举例:

        第一行:W:代表球队1打赢这只队伍

                      L:代表球队2没打赢这只队伍

        因为两队伍有两场比赛,所以互相都可能打败对方;

        如果A队打赢过B队,就连一条A到B的有向边;

        建边时注意,如果A队 "L" B队,就连一条B->A边;(忘了这个wa了一发)

        (这是坑点1,不是最可怕的)

    4. 目的:

        找到一条食物链:1 3 5 4 2;

        代表:1赢过3,3赢过5,5赢过4,4赢过2,并且 2赢过1

        要循环的;

    解题思路:

    1. 很明显dfs可以解决;如果A队打赢过B队,就连一条A到B的有向边;

        (因为我很傻以为球队有很多只,怕超时,sb的用set写,其实这个二维数组建边就行了,不过两种写法差别不大,我就当作 是温习一下set的知识。结果被set一个坑点卡了一晚上,贼气,我在结尾说这个蛋疼的故事)

    2. 减枝:状压一下吧(应该是叫状压吧?唉,我太菜了)

        state[cur][i]表示状态cur的最后一步是i;

        如果为1,代表这个不可行,continue掉;

    题目链接:https://www.patest.cn/contests/gplt/L3-015

    (怎么弄超链接,我真的不会)

    AC代码如下:

    #include<bits/stdc++.h>  
    #define test printf("***
    ")  
    #define ka getchar();getchar()  
    #define ka1 getchar()  
    using namespace std;  
    typedef long long LL;  
    const int N = 110;  
    const int M = 1000005;  
    const int INF = 0x3f3f3f3f;  
    const LL mod = 1000000007;  
    const double eps=1e-8;  
    int vis[N],ans[N];  
    int state[1<<21][N];//坑点1,状压处理  
    set<int> son[N];  
    char ar[N][N];  
    int flag,n;  
    void dfs(int u,int t,int cur){  
        if(flag)return;  
        for(set<int>::iterator p=son[u].begin();p!=son[u].end();++p){  
            int tmp=*p;  
            if(t==n){  
                if(tmp==ans[0]){  
                    flag=1;  
                    return;  
                }  
                continue;  
            }  
            if(vis[tmp]||state[cur|(1<<tmp)][tmp])continue;  
            vis[tmp]=1;  
            ans[t]=tmp;  
            dfs(tmp,t+1,cur|(1<<tmp));  
            if(flag)return;  
            state[cur|(1<<tmp)][tmp]=1;  
            vis[tmp]=0;  
        }  
    }  
    int main(){  
        flag=0;  
        scanf("%d",&n);  
        for(int i=0;i<=n;++i){  
            son[i].clear();  
        }  
        for(int i=0;i<n;++i){  
            scanf("%s",ar[i]);  
            for(int j=0;j<n;++j){  
                if(ar[i][j]=='W'){  
                    son[i].insert(j);  
                }  
                if(ar[i][j]=='L'){  
                    son[j].insert(i);//坑点2,双循环赛制  
                }  
            }  
        }  
        memset(vis,0,sizeof(vis));  
        vis[0]=1;  
        ans[0]=0;  
        dfs(0,1,1);  
        if(flag==0){  
            printf("No Solution
    ");  
            return 0;  
        }  
        for(int i=0;i<n;++i){  
            if(i!=n-1) printf("%d ",ans[i]+1);  
            else printf("%d
    ",ans[i]+1);  
        }  
        return 0;  
    }  
    View Code

    (set遍历元素不是要先:set<int>::iterator 吗;然后我 set<int>::iterator p,把p作为全局变量,然后dfs找bug找一晚上,至于为什么不要设为全局变量,自己试一下就知道了)

    (写完csdn再写博客园,真累)

    ACMer,无怨无悔
  • 相关阅读:
    03、CPU主频,和性能
    02、计算机组成原理相关知识
    常用正则表达式,手机号、固话号、身份证号等
    01、计算机原理结构,及冯诺依曼体系结构
    7-7 Complete Binary Search Tree (30分) 完全二叉搜索树
    7-2 Reversing Linked List (25分)
    7-1 Maximum Subsequence Sum (25分)
    6-17 Shortest Path [4] (25分)
    6-16 Shortest Path [3] (25分)
    6-15 Iterative Mergesort (25分)
  • 原文地址:https://www.cnblogs.com/Cwolf9/p/8653785.html
Copyright © 2011-2022 走看看