HDU 4068【全排列枚举简单题】

题目:SanguoSHA

题意:

三国杀1vs1,给出英雄之前的约束关系,无论对手如何安排英雄pk顺序,是否都有机会赢。

解题思路:

比赛时第二道看的题目,看到N小于等于6时就果断敲了。对自己英雄从字典序最小生成全排列,对应一个全排列对对手生成全排列,如果自己的英雄当前的排列能战胜对手的全排列,则当前英雄序列为解。

View Code
 1 #include <iostream>
2 #include <cstdio>
3 #include <string>
4 #include <cstring>
5 #include <algorithm>
6 #include <vector>
7 #include <map>
8
9 using namespace std;
10
11 const int MAX = 10;
12 string Name[MAX];
13 int main()
14 {
15 freopen("in.txt", "r", stdin);
16 int T;
17 int t = 1;
18 int n;
19 scanf("%d", &T);
20 while(T--)
21 {
22 scanf("%d", &n);
23 for(int i = 0; i < n; ++i)
24 cin >> Name[i];
25 sort(Name, Name + n);
26 vector<string> vec[MAX];
27 int k;
28 string temp;
29 for(int i = 0; i < n; ++i)
30 {
31 scanf("%d", &k);
32 for(int j = 0; j < k; ++j)
33 {
34 cin >> temp;
35 vec[i].push_back(temp);
36 }
37 }
38 bool isok = false;
39 int order[MAX];
40 do
41 {
42 for(int i = 0; i < n; ++i)
43 order[i] = i;
44 bool ok = true;
45 do
46 {
47 int p1 = 0, p2 = 0;
48 while(p1 < n && p2 < n)
49 {
50 vector<string>::iterator ix = vec[order[p2]].begin();
51 while(ix != vec[order[p2]].end())
52 {
53 if(*ix == Name[p1])
54 {
55 ++p1;
56 break;
57 }
58 ++ix;
59 }
60 if(ix == vec[order[p2]].end())
61 ++p2;
62 }
63 if(p2 < n)
64 {
65 ok = false;
66 break;
67 }
68 }while(next_permutation(order, order + n));
69 if(ok)
70 {
71 isok = true;
72 break;
73 }
74 }while(next_permutation(Name, Name + n));
75 printf("Case %d: ", t++);
76 if(isok)
77 {
78 printf("Yes\n");
79 for(int i = 0; i < n; ++i)
80 {
81 if(i != 0)
82 cout << " ";
83 cout << Name[i];
84 }
85 printf("\n");
86 }
87 else
88 printf("No\n");
89 }
90 return 0;
91 }



你可能感兴趣的:(HDU)