原题链接: P5380

挺好写的一道比较出名的题解,思路顺畅就没什么问题。

那么我们就以这道题为例,尝试探究分析条件复杂的问题的方法,探索条理清晰的答题思路。

审题:

拿到一道大模拟的时候,首先要做的就是审清题,决定要做这道题的话,一定要保持程序的条理性。

通过对于题目问题的分析我们发现:本题并没有想象中的类似猪国杀的按照某一规则移动棋子,而是对于给定的操作序列判断其是否合法,并处理出相应的一些状态。

那么这道题显然是一道判定类题目,总之要比求解类好些的多,让我们继续分析:

我们要判断操作是否合法——这是这道题最难的一部分。在这之后,在棋盘上移动棋子的过程也变得十分简单——操作合法的话,看看你移动到的位置是否有对方棋子,若有的话则吃掉。剩下的操作是判断将军局面和游戏结束。游戏结束自然简单——如果将帅少了其中之一游戏自然结束。判断将军似乎很难,实际上你只需要遍历棋盘,判断每颗棋子移动到对方将(帅)的移动操作是否合法即可。显然,当一方棋子存在一步合法移动到达对方将(帅)的位置时,我们称此时构成了一个将军局面。

那么我们的实现思路逐渐清晰起来: 我们要完成的核心操作是对于一个棋盘上的任意棋子,判断其到达任意一个位置的操作是否合法。

然后这道题没了(

然后我们的审题工作大致完成,接下来考虑怎么实现这个操作:

实现:

我们考虑怎么实现,因为移动非法的情况较多,而合法移动却只有几种,我们考虑枚举合法情况与给定的移动进行匹配,匹配的上则合法,否则不合法。

那么对于移动前和移动后的位置,我们发现我们只需要关系位置的变化量,这也是题面给出合法位移的方式。同时我们发现用相同的方法可以对任意位置处理出可以影响其移动是否合法的所有位置——对于马,象,鸭的“蹩马腿”情况就是观察“会蹩马腿的位置棋盘上是否有棋子”,那么这些位置相对于初始位置的位移也是一个位置变化量,我们可以用类似于向量的方式来处理这些位置的变化量。

那么显然我们可以写一些“矩阵”来简单地处理这种情况:

我们显然可以使用两个矩阵来分别存储棋盘的每个位置的棋子及其所属阵营——显然这两个矩阵会被同步更新。

然后我们可以使用一个“位移”矩阵来记录每颗棋子的可达位置(虽然车显然要另外考虑),再用一个“非法”矩阵来巨鹿每颗棋子位移会受那些相对位置的影响(虽然对于大多数棋子是空的,并且车再次除外)。这样我们至少可以比较完美地解决马、象和鸭的问题。

于是我们发现了“鸭棋”比中国象棋在实现上困难一点的地方: 鸭的移动非常古怪。
于是我们分析鸭的移动,可以画出这样一张图(因为不会画图所以用LaTeX矩阵凑合看看罢):

(我甚至在源码里码齐了这个矩阵,大概长这样虽然没啥用

1
2
3
4
5
6
7
8
9
\begin{bmatrix}
& t & & & & t & \\
t & & \nwarrow & & \nearrow & & t \\
& \nwarrow & & \uparrow & & \nearrow & \\
& & \gets & s & \to & & \\
& \swarrow & & \downarrow & & \searrow & \\
t & & \swarrow & & \searrow & & t \\
& t & & & & t &
\end{bmatrix}

如果LaTeX炸掉的话可以用公式去找个公式编辑器预览一下这个图(

其中s表示开始移动时的位置,t表示经过会被箭头位置“蹩马腿”后鸭的对应可达位置。我们观察这张图发现:

对于每一个可达位置,都有一个特定的斜向箭头的位置与之对应,而两个同方向的可达位置,共用一个水平/竖直箭头的位置。于是我们考虑在“非法矩阵”中先记录下每种位移的特定箭头的位置,再使用“除二向下取整”加上特定位置的数量得到共用箭头的编号。

说了这么久,放一下代码罢。我们约定代码中数字与棋子和阵营的对应关系如以下函数所示:

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
void print_cap(int camp,int x)
{
if(camp == 1) printf("red ");
else printf("blue ");
switch (x)
{
case 1:
{
printf("captain;");
break;
}
case 2:
{
printf("guard;");
break;
}
case 3:
{
printf("elephant;");
break;
}
case 4:
{
printf("horse;");
break;
}
case 5:
{
printf("car;");
break;
}
case 6:
{
printf("duck;");
break;
}
case 7:
{
printf("soldier;");
break;
}
default:
break;
}
return;
}

应该算是简明易懂了罢。那么我们初始的“棋盘”矩阵如下:

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
int mp[N][N] = 
{
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,5,4,3,2,1,2,3,4,5,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,6,0,0,0,0,0,0,0,6,0,0},
{0,7,0,7,0,7,0,7,0,7,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,7,0,7,0,7,0,7,0,7,0,0},
{0,6,0,0,0,0,0,0,0,6,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,5,4,3,2,1,2,3,4,5,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}
};
int camp[N][N] =
{
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,1,0,0},
{0,1,0,1,0,1,0,1,0,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,2,0,2,0,2,0,2,0,2,0,0},
{0,2,0,0,0,0,0,0,0,2,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,2,2,2,2,2,2,2,2,2,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}
};

我们定义一个结构体 $move$ 来表示“位移”,这样就可以重载一些运算符:

1
2
3
4
5
6
7
8
9
10
11
12
13
struct move{
int x,y;
move(){}
move(int _x,int _y):x(_x),y(_y){}
friend move operator + (move a,move b)
{return (move){a.x + b.x,a.y + b.y};}
friend move operator - (move a,move b)
{return (move){a.x - b.x,a.y - b.y};}
friend bool operator == (move a,move b)
{return a.x == b.x && a.y == b.y;}
friend bool operator != (move a,int b)
{return a.x != b && a.y != b;}
};

由于其中是由横纵坐标来确定相对位置,我们也可以使用这个类型来表示“位置”,就像是坐标系中的点。

1
typedef move pos;

前置工作完成,接下来可以完成剩下的两个矩阵了。
“位移”矩阵如下:

1
2
3
4
5
6
7
8
9
10
11
move right_move[8][9] = 
{
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*0, 0*/
{{ 0, 0},{ 1, 0},{-1, 0},{ 0, 1},{ 0,-1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*1, 4*/
{{ 0, 0},{ 1, 1},{-1,-1},{ 1,-1},{-1, 1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*2, 4*/
{{ 0, 0},{ 2, 2},{-2, 2},{ 2,-2},{-2,-2},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*3, 4*/
{{ 0, 0},{ 2, 1},{-2, 1},{ 2,-1},{-2,-1},{ 1, 2},{-1, 2},{ 1,-2},{-1,-2}},/*4, 8*/
{{ 0, 0},{ 1, 0},{-1, 0},{ 0, 1},{ 0,-1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*5,17*/
{{ 0, 0},{ 2, 3},{-2, 3},{ 2,-3},{-2,-3},{ 3, 2},{ 3,-2},{-3, 2},{-3,-2}},/*6, 8*/
{{ 0, 0},{ 1, 0},{-1, 0},{ 0, 1},{ 0,-1},{ 1, 1},{-1, 1},{ 1,-1},{-1,-1}},/*7, 8*/
};

最后的注释是棋子编号和对应的元素(可达位置或“蹩马腿”位置)的数量,便于查验

“非法”矩阵如下:

1
2
3
4
5
6
7
8
9
10
11
move ban_move[8][13] = 
{
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*0, 0*/
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*1, 0*/
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*2, 0*/
{{ 0, 0},{ 1, 1},{-1, 1},{ 1,-1},{-1,-1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*3, 4*/
{{ 0, 0},{ 1, 0},{-1, 0},{ 1, 0},{-1, 0},{ 0, 1},{ 0, 1},{ 0,-1},{ 0,-1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*4, 8*/
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*5, 0*/
{{ 0, 0},{ 1, 2},{-1, 2},{ 1,-2},{-1,-2},{ 2, 1},{ 2,-1},{-2, 1},{-2,-1},{ 0, 1},{ 0,-1},{ 1, 0},{-1, 0}},/*6,12*/
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*7, 0*/
};

然后就没了,所以敲这个矩阵的时候建议不要复制粘贴01串(因为手敲交互真的很爽)

剩下的部分我觉得没什么东西了,所以就把完整代码贴一下完事。我觉得我的变量名写的比较通俗移动所以有问题的话大概看看就能看明白罢(当然如果你想CV的话,我并没有加入防抄袭)

代码:

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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
#include<bits/stdc++.h>
namespace Pozhu{
using namespace std;
#define N 12
struct move{
int x,y;
move(){}
move(int _x,int _y):x(_x),y(_y){}
friend move operator + (move a,move b)
{return (move){a.x + b.x,a.y + b.y};}
friend move operator - (move a,move b)
{return (move){a.x - b.x,a.y - b.y};}
friend bool operator == (move a,move b)
{return a.x == b.x && a.y == b.y;}
friend bool operator != (move a,int b)
{return a.x != b && a.y != b;}
};

typedef move pos;
int mp[N][N] =
{
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,5,4,3,2,1,2,3,4,5,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,6,0,0,0,0,0,0,0,6,0,0},
{0,7,0,7,0,7,0,7,0,7,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,7,0,7,0,7,0,7,0,7,0,0},
{0,6,0,0,0,0,0,0,0,6,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,5,4,3,2,1,2,3,4,5,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}
};
int camp[N][N] =
{
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,1,1,1,1,1,1,1,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,0,0,0,0,0,0,1,0,0},
{0,1,0,1,0,1,0,1,0,1,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,2,0,2,0,2,0,2,0,2,0,0},
{0,2,0,0,0,0,0,0,0,2,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,2,2,2,2,2,2,2,2,2,0,0},
{0,0,0,0,0,0,0,0,0,0,0,0}
};
move right_move[8][9] =
{
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*0, 0*/
{{ 0, 0},{ 1, 0},{-1, 0},{ 0, 1},{ 0,-1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*1, 4*/
{{ 0, 0},{ 1, 1},{-1,-1},{ 1,-1},{-1, 1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*2, 4*/
{{ 0, 0},{ 2, 2},{-2, 2},{ 2,-2},{-2,-2},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*3, 4*/
{{ 0, 0},{ 2, 1},{-2, 1},{ 2,-1},{-2,-1},{ 1, 2},{-1, 2},{ 1,-2},{-1,-2}},/*4, 8*/
{{ 0, 0},{ 1, 0},{-1, 0},{ 0, 1},{ 0,-1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*5,17*/
{{ 0, 0},{ 2, 3},{-2, 3},{ 2,-3},{-2,-3},{ 3, 2},{ 3,-2},{-3, 2},{-3,-2}},/*6, 8*/
{{ 0, 0},{ 1, 0},{-1, 0},{ 0, 1},{ 0,-1},{ 1, 1},{-1, 1},{ 1,-1},{-1,-1}},/*7, 8*/
};
move ban_move[8][13] =
{
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*0, 0*/
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*1, 0*/
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*2, 0*/
{{ 0, 0},{ 1, 1},{-1, 1},{ 1,-1},{-1,-1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*3, 4*/
{{ 0, 0},{ 1, 0},{-1, 0},{ 1, 0},{-1, 0},{ 0, 1},{ 0, 1},{ 0,-1},{ 0,-1},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*4, 8*/
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*5, 0*/
{{ 0, 0},{ 1, 2},{-1, 2},{ 1,-2},{-1,-2},{ 2, 1},{ 2,-1},{-2, 1},{-2,-1},{ 0, 1},{ 0,-1},{ 1, 0},{-1, 0}},/*6,12*/
{{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0},{ 0, 0}},/*7, 0*/
};
int Q;
pos sta,end;
bool end_game;
int now_player = 1; // 1 -> red;2 -> blue
int now_chess;
int eat_chess;
bool kill_the_captain;
int tot_ban[8] = {0,0,0,4,8,0,12,0};
int tot_move[8] = {0,4,4,4,8,17,8,8};

void work();
void init();
int _mp(pos );
void eat(pos );
int _camp(pos );
void print_map();
bool out_of(pos );
bool if_end_game();
void print_cap(int ,int );
void move_chess(pos ,pos );
bool if_kill_the_captain();
bool if_right_move(pos ,pos );

void main()
{
scanf("%d",&Q);
while(Q--) work();
return;
}

inline void work()
{
#define PE {puts("Invalid command");return;}
int sx,sy,tx,ty;
scanf("%d%d%d%d",&sx,&sy,&tx,&ty);
sx++,sy++,tx++,ty++;
sta = (pos){sx,sy};
end = (pos){tx,ty};
if(end_game) PE;
if(out_of(sta)) PE;
if(out_of(end)) PE;
if(sta == end) PE;
if(!_mp(sta)) PE;
if(_camp(sta) != now_player) PE;
init();
now_chess = _mp(sta);
if(!if_right_move(sta,end)) PE;
move_chess(sta,end);

kill_the_captain = if_kill_the_captain();
print_cap(now_player,now_chess);
if(eat_chess)
print_cap(3 - now_player,eat_chess);
else
printf("NA;");
if(kill_the_captain)
printf("yes;");
else
printf("no;");
if(end_game)
printf("yes\n");
else
printf("no\n");
now_player = 3 - now_player;
#undef PE
return;
}

bool if_kill_the_captain()
{
pos red_captain = (pos){0,0};
pos blue_captain = (pos){0,0};
pos zero = (pos){0,0};
for(int i = 1;i<=10;i++)
for(int j = 1;j<=9;j++)
if(mp[i][j] == 1)
{
if(camp[i][j] == 1) red_captain = (pos){i,j} ;
else blue_captain = (pos){i,j};
}
if(red_captain == zero || blue_captain == zero)
{
end_game = true;
return false;
}
for(int i = 1;i<=10;i++)
for(int j = 1;j<=9;j++)
if(mp[i][j])
{
if(camp[i][j] == 1)
{
if(if_right_move((pos){i,j},blue_captain))
return true;
}
else
{
if(if_right_move((pos){i,j},red_captain))
return true;
}
}
return false;
}

bool if_right_move(pos sta,pos end)
{
if(out_of(sta)) return false;
if(out_of(end)) return false;
if(sta == end) return false;
if(_camp(sta) == _camp(end)) return false;
int now_chess = _mp(sta);
pos mv = end - sta;
switch (now_chess)
{
case 1:
{
// printf("captain ");
bool flag = 0;
for(int i = 1;i<=tot_move[1];i++)
if(mv == right_move[1][i])
{flag = 1;break;}
if(!flag) return false;
break;
}
case 2:
{
// printf("guard ");
bool flag = 0;
for(int i = 1;i<=tot_move[2];i++)
if(mv == right_move[2][i])
{flag = 1;break;}
if(!flag) return false;
break;
}
case 3:
{
// printf("elephant ");
bool flag = 0;
int k;
for(k = 1;k<=tot_move[3];k++)
if(mv == right_move[3][k])
{flag = 1;break;}
if(!flag) return false;
if(_mp(sta+ban_move[3][k])) return false;
break;
}
case 4:
{
// printf("horse ");
bool flag = 0;
int k;
for(k = 1;k<=tot_move[4];k++)
if(mv == right_move[4][k])
{flag = 1;break;}
if(!flag) return false;
if(_mp(sta+ban_move[4][k])) return false;
break;
}
case 5:
{
// printf("car ");
if(sta.x != end.x && sta.y != end.y)
return false;
if(sta.x == end.x)
{
if(sta.y < end.y)
{
int y;
for(y = sta.y+1;y < end.y;y++)
{
if(!mp[sta.x][y]) continue;
return false;
}
}
if(sta.y > end.y)
{
int y;
for(y = sta.y-1;y > end.y;y--)
{
if(!mp[sta.x][y]) continue;
return false;
}
}
}
if(sta.y == end.y)
{
if(sta.x < end.x)
{
int x;
for(x = sta.x+1;x<end.x;x++)
{
if(!mp[x][sta.y]) continue;
return false;
}
}
if(sta.x > end.x)
{
int x;
for(x = sta.x - 1;x > end.x;x--)
{
if(!mp[x][sta.y]) continue;
return false;
}
}
}
break;
}
case 6:
{
// printf("duck ");
bool flag = 0;
int k;
for(k = 1;k<=tot_move[6];k++)
if(mv == right_move[6][k])
{flag = 1;break;}
if(!flag) return false;
if(_mp(sta+ban_move[6][k])) return false;
if(_mp(sta+ban_move[6][8+(k+1)/2])) return false;
break;
}
case 7:
{
// printf("soldier ");
bool flag = 0;
for(int i = 1;i<=tot_move[7];i++)
if(mv == right_move[7][i])
{flag = 1;break;}
if(!flag) return false;
break;
}
default:
break;
}
return true;
}

void eat(pos x)
{
eat_chess = _mp(x);
}

void move_chess(pos a,pos b)
{
eat(b);
mp[b.x][b.y] = mp[a.x][a.y];
camp[b.x][b.y] = camp[a.x][a.y];
mp[a.x][a.y] = 0;
camp[a.x][a.y] = 0;
}

void init()
{
eat_chess = 0;
now_chess = 0;
}

bool out_of(pos x)
{
return ((x.x < 1) || (x.x > 10) || (x.y < 1) || (x.y > 9));
}

int _camp(pos x)
{
return camp[x.x][x.y];
}

int _mp(pos x)
{
return mp[x.x][x.y];
}

void print_cap(int camp,int x)
{
if(camp == 1) printf("red ");
else printf("blue ");
switch (x)
{
case 1:
{
printf("captain;");
break;
}
case 2:
{
printf("guard;");
break;
}
case 3:
{
printf("elephant;");
break;
}
case 4:
{
printf("horse;");
break;
}
case 5:
{
printf("car;");
break;
}
case 6:
{
printf("duck;");
break;
}
case 7:
{
printf("soldier;");
break;
}
default:
break;
}
return;
}

void print_map()
{
for(int i = 1;i<=10;i++)
{
for(int j = 1;j<=9;j++)
cerr << mp[i][j] << ' ';
cerr << endl;
}
return;
}

}

signed main()
{
Pozhu :: main();
return 0;
}

当时仨小时左右写完了这道题(比写题解不慢),略微调了一下过了样例,然后交上去就一遍过了(所以清晰的思路对于大模拟来说很主要)

by Pozhu
2022.8.12