zoukankan      html  css  js  c++  java
  • hdu 4068 SanguoSHA

                                                                         SanguoSHA

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
    Total Submission(s): 1246    Accepted Submission(s): 685


    Problem Description
    Sanguosha has a singled version. Two players each select N heroes and start fighting. If a hero dies, the next follows. If one player's heroes are all dead, he loses.
    There're restraints among heroes. For example, YuJi restricts Zhu Geliang, LuXun restricts DaQiao, ZhangJiao restricts MaChao, WeiYan restricts XiaoQiao.
    Today I play with friends. I know the heroes and the restraints.(If opponent's hero restraint my hero, my hero will be beaten, others my hero will beat opponent's hero)
    Can you arrange my heroes' order,no matter what order of opponent's heroes, so that I can win the game?
     
    Input
    The first line is a number T(1<=T<=50), represents the number of case. The next T blocks follow each indicates a case.
    The first line is N(3<=N<=6).
    The second line has N names(shorter than 20 letter).
    The following N lines each contains a restraints. Restraints are given as “k b1 b2 … bk”, which means the opponent's hero restricts my hero b1, b2 … bk. (0<=K<=N)
     
    Output
    For each case, first line output the number of case with "Yes" or "No". If Yes, output the order of your heroes separate by a space. If there are more than one order, please output the one with minimum lexicographic order.(as shown in the sample output)
     
    Sample Input
    2 3 ZhugeLiang HuangYueying ZhenJi 1 ZhugeLiang 2 HuangYueying ZhenJi 2 ZhugeLiang ZhenJi 4 MaChao YanLiangWenChou YuJin XiaoQiao 2 MaChao XiaoQiao 2 YanLiangWenChou YuJin 1 XiaoQiao 0
     
    Sample Output
    Case 1: No
    Case 2: Yes
    MaChao YanLiangWenChou XiaoQiao YuJin
     
    题意:三国杀1v1,双方都有N张武将牌,武将牌之间有克制的关系,一方的武将牌要么被对方克制,要么克制对方,一旦武将牌被对方克制,该武将就会战败,换下一张武将牌继续打;否则,一直战斗,直到该武将战败或者对方没有武将了为止。
    现在要求你找出一种组合,使得无论对方怎么排列自己的武将牌顺序,你都将立于不败之地,如果有多种情况,则输出武将名字的字典序最小的情况。
    思路:
    排列组合,暴力枚举,对于我方的每一种可能的武将出场顺序组合,穷尽对方的每一种武将牌出场顺序,如果都被我方当前的武将牌出场顺序所打败,那么这种出场顺序是可行的,找到字典序最小的组合即可。
    AC代码:
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    using namespace std;
    const int N_MAX = 6;
    string s[N_MAX];
    set<string>Set[N_MAX];
    
    int main() {
        int T,t=0;
        scanf("%d",&T);
        while (T--) {
            t++;
            int N;
            scanf("%d",&N);
            for (int i = 0; i < N; i++) {
                cin >> s[i];
            }
            sort(s, s + N);//以字典序从小到大排
            for (int i = 0; i < N; i++) {
                int num;
                scanf("%d",&num);
                for (int j = 0; j < num; j++) {
                    string ss;
                    cin >> ss;
                    Set[i].insert(ss);
                }
            }
            sort(Set, Set + N);//!!!!字典序排列
            
            bool flag = 0; int a=0;
            do{//对于每一种武将排列的组合,判断一下是否符合要求
                flag = 1;
                do {//无论对方的牌怎么换,都要成功打败才可以
                    int i = 0;
                    int ant = 0;
                    while (i <N && ant<N) {
                        set<string>::iterator it = Set[i].find(s[ant]);//在集合中找有没有克制武将s[ant]的
                        if (it != Set[i].end()) {//该武将被克制了
                            ant++;//换下一个武将
                        }
                        else { 
                            i++;//挑战下一位        
                        }
                    }
                    if (i<N) { flag = 0; break; }//失败
                } while(next_permutation(Set,Set+N));//从最小字典序开始考虑每一种排列
    
                if (!flag) {//!!!!!!上一次失败了,为了下一次继续运行Set的排列组合时从最小字典序开始,就要归位
                    while (prev_permutation(Set, Set + N));
                    next_permutation(Set, Set + N);
                }//!!!
                if (flag)break;//成功
            } while (next_permutation(s, s + N));
    
            if (flag) {
                printf("Case %d: Yes
    ", t);
                for (int i = 0; i < N; i++) {
                    if(i==0)cout << s[i] ;
                    else cout <<" "<< s[i];
                }
                printf("
    ");
            }
            else printf("Case %d: No
    ",t);
    
            for (int i = 0; i < N;i++) {
                Set[i].clear();
            }
        }
        return 0;
    }
     
  • 相关阅读:
    md基本语法
    CodeBlocks安装使用、汉化以及更改配色
    hexo+github搭建个人博客教程和各种坑记录
    GB/T 38637.1-2020 物联网 感知控制设备接入 第1部分:总体要求
    山东大学909数据结构与程序设计考研经验分享
    GB/T 39083-2020 快递服务支付信息交换规范
    GB/T 38829-2020 IPTV媒体交付系统技术要求 内容接入
    GB/T 37733.3-2020 传感器网络 个人健康状态远程监测 第3部分:终端技术要求
    GB/T 38801-2020 内容分发网络技术要求 互联应用场景
    GB/T 30269.809-2020 信息技术 传感器网络 第809部分:测试:基于IP的无线传感器网络网络层协议一致性测试
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/6686427.html
Copyright © 2011-2022 走看看