题目描述:
石头剪子布游戏,总共N个小孩,把N - 1个分成3组,每组的小孩每次只能出固定的。一人为裁判,每次可以随意出。进行M场比赛,结果用X>Y、X<Y、X=Y表示。问经过几轮能推断出裁判的ID。
石头剪子布游戏,总共N个小孩,把N - 1个分成3组,每组的小孩每次只能出固定的。一人为裁判,每次可以随意出。进行M场比赛,结果用X>Y、X<Y、X=Y表示。问经过几轮能推断出裁判的ID。
题目类型:并查集
解题思路:
(1)依次假设每个小孩为裁判,遍历每个比赛(遇到有该小孩的则跳过),用并查集求出产生矛盾的轮数。若有多个人没产生矛盾,输出Can not determine。若所有人都产生矛盾,输出Impossible。若只有一人没产生矛盾,则其为裁判,其余小孩产生矛盾的最大轮数是推断出裁判的最大轮数。
(2)节点与根节点的关系:根为0,若根胜则节点值为2,若根负则节点值为1,若根平则节点值为0。合并两个树时,讲r2合并到r1,即root[r2] = r1。更新关系:relation[r2] = (relation[s1] - relation[s2] + relation[r1] + r + 3) % 3。判断两节点是否矛盾:(relation[s1] + r) % 3 == relation[s2],相等说明不矛盾。
(1)依次假设每个小孩为裁判,遍历每个比赛(遇到有该小孩的则跳过),用并查集求出产生矛盾的轮数。若有多个人没产生矛盾,输出Can not determine。若所有人都产生矛盾,输出Impossible。若只有一人没产生矛盾,则其为裁判,其余小孩产生矛盾的最大轮数是推断出裁判的最大轮数。
(2)节点与根节点的关系:根为0,若根胜则节点值为2,若根负则节点值为1,若根平则节点值为0。合并两个树时,讲r2合并到r1,即root[r2] = r1。更新关系:relation[r2] = (relation[s1] - relation[s2] + relation[r1] + r + 3) % 3。判断两节点是否矛盾:(relation[s1] + r) % 3 == relation[s2],相等说明不矛盾。
运行结果:500MS + 200K
View Code
1 #define _CRT_SECURE_NO_WARNINGS
2 #include "stdio.h"
3 #include "string.h"
4
5 int N, M, root[501], relation[501];
6 struct ROUND { int s1, s2, r; } round[10001];
7
8 int find(int s)
9 {
10 if (root[s] != s)
11 {
12 int r = root[s];
13 root[s] = find(root[s]);
14 relation[s] = (relation[s] + relation[r]) % 3;
15 }
16 return root[s];
17 }
18
19 bool add(int s1, int s2, int r)
20 {
21 int r1 = find(s1);
22 int r2 = find(s2);
23
24 if (r1 != r2) root[r2] = r1, relation[r2] = (relation[s1] - relation[s2] + relation[r1] + r + 3) % 3;
25 else if ((relation[s1] + r) % 3 != relation[s2]) return false;
26 return true;
27 }
28
29 void solve()
30 {
31 int judge_sum = 0, judge_num = -1, max_round = -1, k;
32 for (int i = 0; i < N; ++i)
33 {
34 for (k = 0; k < N; ++k) root[k] = k;
35 memset(relation, 0, sizeof(int) * N);
36 for (k = 0; k < M; ++k)
37 {
38 if (round[k].s1 == i || round[k].s2 == i) continue;
39 if (!add(round[k].s1, round[k].s2, round[k].r))
40 {
41 if (k > max_round) max_round = k;
42 break;
43 }
44 }
45 if (k == M) ++judge_sum, judge_num = i;
46 }
47
48 if (judge_sum == 0) printf("Impossible\n");
49 else if (judge_sum > 1) printf("Can not determine\n");
50 else printf("Player %d can be determined to be the judge after %d lines\n",
51 judge_num, max_round + 1);
52 }
53
54 int main()
55 {
56 while (scanf("%d%d", &N, &M) != -1)
57 {
58 for (int i = 0; i < M; ++i)
59 {
60 scanf("%d", &round[i].s1);
61 char ch = getchar();
62 round[i].r = (ch == '>' ? 2 : (ch == '<' ? 1 : 0));
63 scanf("%d", &round[i].s2);
64 }
65 solve();
66 }
67 return 0;
68 }

浙公网安备 33010602011771号