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;
    }
     
  • 相关阅读:
    git 记录
    js 技巧
    首页三张幻灯片放什么
    6系统盈利方向
    WordPress获取某个分类关联的标签
    目标型长尾如何优化
    简介如何去除WordPress主题版权保护的方法
    2017.7.7 长尾关键词系统优化
    2017.7.6 目标关键词分析
    2017.7.2 seo知识总纲
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/6686427.html
Copyright © 2011-2022 走看看