• hdu 4068 SanguoSHA


    暴力题

    选拔赛的题目当时想歪了也不敢下手做

    题意:三国杀,我方和敌方都有n人,会给出我方武将的全部名字。然后下面n行,第i行先输入一个m,后面跟着m个名字,表示敌方第i个武将能克制我方的这m个武将,没有列出名字的武将则会克制敌方的第i个武将。两方对战,一方武将死了下一位补上,直到一方武将全部死亡则该方输掉了游戏。问你是否能构建出一种无敌的出场方式,无论敌方怎么派出武将,我方都必将取得胜利,如果不能输出No,能的话,输出Yes,另外如果有多种无敌序列,要按名字字典序输出(是指单个单个名字比较,而不是把全部名字压成一个字符串再比较)

    由于数据规模很小n最大为6,所以其实是个水题,只要暴力枚举两方的全排列然后逐一比较即可

    1.我方武将和敌方武将都从0到n-1标号。构建一个01矩阵g[i][j]=1,表示敌方的第i个武将能杀死我方的第i个武将,=0则表示不能杀死

    2.枚举全排列用STL来写,但是注意用next_permutation()之前要先排序(或者你能保证一开始时是字典序最小序列),太久没用这个函数忘记排序WA了好几次

    3.枚举全排列其实可以不用像代码中那样写,可以先把所有排列保存下来,以后直接用即可,可以节省时间,另外用dfs手打全排列也能提高时间,代码中为了方便就用STL

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LEN 25
    #define N 10
    using namespace std;
    
    bool g[N][N];
    char name[N][LEN];
    int n;
    int p1[N],p2[N];
    
    void change(int *ans)
    {
        int x,y,OK=0;
        for(int i=0; i<n; i++)
        {
            x=ans[i];
            y=p1[i];
            if(strcmp(name[x],name[y]) < 0) 
                break;
            else if(strcmp(name[y],name[x]) < 0)
            {
                OK=1;
                break;
            }
        }
        if(OK)
            for(int i=0; i<n; i++)
                ans[i]=p1[i];
    }
    
    bool fight()
    {
        int i=0,j=0,x,y;
        while(i<n && j<n)
        {
            x=p1[i];
            y=p2[j];
            if(g[y][x]) i++;
            else        j++;
        }
        return i<n;
    }
    
    void solve(int Case)
    {
        for(int i=0; i<n; i++) p1[i]=p2[i]=i;
    
        int ans[N],FIND,OK;
        FIND=0;
    
        do
        {
            sort(p2,p2+n);
            OK=1;
            do
            {
                if(!fight())
                {
                    OK=0;
                    break;
                }
            }
            while(next_permutation(p2,p2+n)); 
           
            if(OK)
            {
                if(!FIND)
                {
                    FIND=1;
                    for(int i=0; i<n; i++) 
                        ans[i]=p1[i];
                }
                else 
                    change(ans);
            }
        }
        while(next_permutation(p1,p1+n)); 
    
        if(!FIND)
            printf("Case %d: No\n",Case);
        else
        {
            printf("Case %d: Yes\n",Case);
            for(int i=0; i<n; i++)
            {
                if(i) printf(" ");
                printf("%s",name[ans[i]]);
            }
            printf("\n");
        }
    }
    
    void input()
    {
        scanf("%d",&n);
        for(int i=0; i<n; i++) 
            scanf("%s",name[i]);
        memset(g,0,sizeof(g));
        for(int i=0; i<n; i++)
        {
            int m;
            char tmp[LEN];
            scanf("%d",&m);
            for(int j=0; j<m; j++)
            {
                scanf("%s",tmp);
                for(int k=0; k<n; k++) if(!strcmp(name[k],tmp))
                {
                    g[i][k]=1;
                    break;
                }
            }
        }
    }
    
    int main()
    {
        int T,t;
        scanf("%d",&T);
        for(t=1; t<=T; t++)
        {
            input();
            solve(t);
        }
        return 0;
    }
  • 相关阅读:
    2019届宝鸡理数质检Ⅱ解析版
    随机事件的概率
    三视图
    求曲线的轨迹方程
    组合法破解二项式系数问题
    二项式定理
    计数原理
    HBase的Shell命令
    HBase伪分布安装
    HBase基础知识
  • 原文地址:https://www.cnblogs.com/scau20110726/p/2954016.html
Copyright © 2020-2023  润新知