红心大战

问题描述:相信大家都有玩过“红心大战”这款游戏。现在有 4 个玩家来进行操作,我们会介绍本题中的游戏规则和玩家的出牌策略,你的任务是根据初始局面来计算最后的得分情况。

游戏开始时, 4 名玩家平分一副扑克牌除去双王后的 52 张牌,即每名玩家13 张牌。点数从小到大为 2,3,4,5,6,7,8,9,10,𝐽, 𝑄,𝐾,𝐴 ,输入中会用 11,12,13,1 来表示 𝐽, 𝑄, 𝐾, 𝐴 。我们另用 1,2,3,4 分别表示梅花、方片、黑桃、红桃四种花色。这样可以用一个二元组来表示一张扑克牌。比如 (2,7) 来表示方片 7 。由于本题中手牌的位置直接影响了玩家的出牌,因此玩家会将手牌排序,规则为先比较花色,再比较点数。如 (1,3), (1,1), (3,10), (4,2), (4,6) 就是排好序的手牌。4 名玩家坐成一圈,一轮出牌定义为从某名玩家开始按顺时针顺序每人各出一张牌。第一轮,从持有梅花 2 的玩家开始出牌,他需要打出梅花 2 。以后每轮,第一个出牌的玩家都会打出手中最左边的一张牌。对于某轮并非第一个出牌的玩家,他会考虑本轮中已经打出的、花色与第一个出牌的玩家打出牌相同的、点数 最大的牌。若该玩家没有与之相同花色的牌,他会将手中最右边的一张牌打出,否则有两种情况:

  1. 若其手中存在与之相同花色且点数更小的牌,他会选择相同花色、点数 更小的牌中点数最大的打出。
  2. 若其手中与之花色相同的牌的点数都更大,他会选择相同花色、点数最 大的牌打出

一轮游戏完成后,打出了与第一个出牌的玩家打出牌花色相同且点数最大的玩家收走这一轮打出的 4 张牌,并由他作为下一轮第一个出牌的玩家开始下一轮。所有牌打完后,统计每名玩家收走的牌。其中每有一张红桃牌,该玩家获得1 分。收走黑桃 𝑄 的玩家得到 13 分。需要注意的是,若一名玩家得到了全部的26 分,则改为他不得分,其他 3 名玩家各得 26 分。可以发现,本题中的规则与实际规则会有出入。本题中 4 名玩家按顺时针的编号为 1,2,3,4 。为了方便选手得到部分分,本题中玩家的牌可能是不完整的,即总量不足 52张,但仍保证每人手牌数量相同、没有相同的牌且梅花 2 在其中一人手中。

大模拟题目,别人写了三个多小时,或者写了两个多小时,我算了算,我差不多也是吧

以下是几个坑点:

  • A最大
  • Q是12不是13
  • 我们所要打出的牌的标准是不断更换的

细节:

  • 结构体可以再套一个结构体
  • 结构体初始化的时候,要带上&

代码如下:(为了纪念我做出的第一道大模拟题,所有的代码痕迹都没有删除)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <bits/stdc++.h>
using namespace std;

typedef pair<int, int>pr;

inline int read()
{
int s(0), w(1);
char ch = getchar();
while (ch < '0' || ch > '9') {if (ch == '-') w = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') s = s * 10 + ch - '0', ch = getchar();
return s * w;
}

inline void put(int x)
{
if (! x) putchar('0');
if (x < 0) putchar('-'), x = -x;
int num(0); char c[66];
while (x) c[++ num] = x % 10 + 48, x /= 10;
while (num) putchar(c[num --]);
return (void)(putchar('\n'));
}

struct yhm
{
int tot, val;
struct fuck
{
int col, big;
bool operator < (const fuck &x) const
{
return (col < x.col) || ((col == x.col) && (big < x.big));
}
}id[66];
}a[6];

vector<pr>v[66], lin;
int now_val[66];

inline void fanzhuan(int x)
{
for (int i = 1; i <= 4; ++ i)
{
if (i == x) continue;
a[i].val += 26;
}
return;
}

inline void add_val()
{
memset(now_val, 0, sizeof now_val);
for (int i = 1; i <= 4; ++ i)
{
for (int j = 0; j < (int)v[i].size(); ++ j)
{
if (v[i][j].first == 4) ++ now_val[i];
if (v[i][j].first == 3 && v[i][j].second == 12) now_val[i] += 13;
}
}

int pd = 0;
for (int i = 1; i <= 4; ++ i)
{
if (now_val[i] == 26)
{
fanzhuan(i);
pd = 1;
}
}
if (pd == 0) for (int i = 1; i <= 4; ++ i) a[i].val += now_val[i];
return;
}

inline void End_print()
{
for (int i = 1; i <= 4; ++ i) cout << a[i].val << ' ';
cout << '\n';
return;
}

signed main()
{
// freopen("hearts.in", "r", stdin), freopen("hearts.out", "w", stdout);
int T = read();
while (T --)
{
for (int i = 0; i <= 6; ++ i) v[i].clear();
memset(now_val, 0, sizeof now_val);
memset(&a, 0, sizeof a);

int n = read(), start;
for (int t = 1; t <= 4; ++ t)
{
a[t].tot = n;
for (int i = 1; i <= n; ++ i)
{
int x = read(), y = read();
if (y == 1) y = 14;
a[t].id[i].col = x;
a[t].id[i].big = y;
if (x == 1 && y == 2) start = t;
}
sort(a[t].id + 1, a[t].id + n + 1);
}
while (n --)
{
lin.clear();
int x = a[start].id[1].col, y = a[start].id[1].big;
lin.push_back(pr(x, y));
for (int i = 1; i < a[start].tot; ++ i) a[start].id[i] = a[start].id[i + 1];
-- a[start].tot;

int tibu = start, start_fuck = 666666, start_val = y;
for (int cnm = tibu; cnm <= 4 + tibu - 1; ++ cnm)
{
int t = cnm % 4;
if (t == 0) t = 4;
if (t == tibu) continue;
int pd = 0;
for (int i = 1; i <= a[t].tot; ++ i) if (a[t].id[i].col == x) pd = 1;
if (pd == 0)
{
int len = a[t].tot;
lin.push_back(pr(a[t].id[len].col, a[t].id[len].big));
}
else
{
int pd_min = 0;
for (int i = 1; i <= a[t].tot; ++ i)
if (a[t].id[i].col == x)if (a[t].id[i].big < start_val) pd_min = 1;
if (pd_min)
{
int mabi;
for (int i = 1; i <= a[t].tot; ++ i)
{
if (a[t].id[i].col == x)
{
if (a[t].id[i].big < start_val)
{
mabi = i;
}
}
}
lin.push_back(pr(a[t].id[mabi].col, a[t].id[mabi].big));
for (int i = mabi; i < a[t].tot; ++ i)
a[t].id[i] = a[t].id[i + 1];
}
else
{
int mabi;
for (int i = 1; i <= a[t].tot; ++ i)
{
if (a[t].id[i].col == x)
{
if (a[t].id[i].big > y)
{
mabi = i;
if (a[t].id[i].big > start_val)
{
start_fuck = t;
start_val = a[t].id[i].big;
}
}
}
}
lin.push_back(pr(a[t].id[mabi].col, a[t].id[mabi].big));
for (int i = mabi; i < a[t].tot; ++ i) a[t].id[i] = a[t].id[i + 1];
}
}
-- a[t].tot;
}

if (start_fuck != 666666) start = start_fuck;
for (int j = 0; j < (int)lin.size(); ++ j)
v[start].push_back(pr(lin[j].first, lin[j].second));
}
add_val();
End_print();
}
return 0;
}