『PG2』猪棋
传送门
题目背景
交互库绝顶聪明。
题目描述
猪棋的规则:
在一个 1000 × 1000 1000\times 1000 1000×1000 的棋盘上,两人分别执黑棋白棋轮流执子,每次可以在当前没有子的不同位置将两颗子分别放下(有序),如果一颗子放下时出现有 ( x , y ) , ( x + 1 , y ) , ( x , y + 1 ) , ( x + 1 , y + 1 ) (x,y),(x+1,y),(x,y+1),(x+1,y+1) (x,y),(x+1,y),(x,y+1),(x+1,y+1) 的四个位置棋子颜色均相同则执此颜色者获胜。
你将扮演先手,在 100 100 100 步内战胜交互库扮演的后手,保证有解。
对于每轮,你可以选择两个坐标 ( x 1 , y 1 ) (x_1,y_1) (x1,y1) 与 ( x 2 , y 2 ) (x_2,y_2) (x2,y2) 落子,你首先需要保证 1 ≤ x 1 , y 1 , x 2 , y 2 ≤ 1000 1\leq x_1,y_1,x_2,y_2\leq 1000 1≤x1,y1,x2,y2≤1000,你其次需要保证没人曾在 ( x 1 , y 1 ) (x_1,y_1) (x1,y1) 落子,如果此时你获胜了判定结束且你获胜,否则你还需保证没人曾经在 ( x 2 , y 2 ) (x_2,y_2) (x2,y2) 落子,如果此时你获胜了判定结束且你获胜,否则交互库将返回一组 x 1 , y 1 , x 2 , y 2 x_1,y_1,x_2,y_2 x1,y1,x2,y2 表示他在 ( x 1 , y 1 ) , ( x 2 , y 2 ) (x_1,y_1),(x_2,y_2) (x1,y1),(x2,y2) 落子,保证 ( x 1 , y 1 ) ≠ ( x 2 , y 2 ) , 1 ≤ x 1 , y 1 , x 2 , y 2 ≤ 1000 (x_1,y_1)\neq (x_2,y_2),1\leq x_1,y_1,x_2,y_2\leq 1000 (x1,y1)=(x2,y2),1≤x1,y1,x2,y2≤1000,如果此时交互库获胜判定结束且你输了,否则判定棋盘上是否已经有 400 400 400 颗子,如果是你获得平局,否则进入你的新一轮。
输入格式
你每轮结束后从标准输入中输入四个整数,代表评测机返回的结果。
输出格式
每轮开始时,你需要向标准输出输出四个 [ 1 , 1000 ] [1,1000] [1,1000] 中的整数,然后清空缓冲区。
你可以使用如下语句来清空缓冲区:
- 对于 C/C++:
fflush(stdout)
; - 对于 C++:
std::cout << std::flush
; - 对于 Java:
System.out.flush()
; - 对于 Python:
stdout.flush()
; - 对于 Pascal:
flush(output)
; - 对于其他语言,请自行查阅对应语言的帮助文档。
特别的,对于 C++ 语言,在输出换行时如果你使用 std::endl
而不是 '\n'
,也可以自动刷新缓冲区。
提示
共 5 5 5 个测试点,在测试点中如果你获胜且每步都满足 6 ≤ x , y ≤ 994 6\leq x,y\leq 994 6≤x,y≤994 你将获得 100 100 100 分,否则获胜你将获得 50 50 50 分,你输了将获得 0 0 0 分,平局获得 30 30 30 分,总分数取测试点最小值。
本题输入输出参考 0 0 0 分程序:
#include <bits/stdc++.h>
using namespace std;
int n;
int x,y,xx,yy;
signed main()
{
int i,j,k;
n=100;
while(n--)
{
cout<<rand()%1000+1<<' '<<rand()%1000+1<<endl;
cout<<rand()%1000+1<<' '<<rand()%1000+1<<endl;
cin>>x>>y>>xx>>yy;
}
return 0;
}
以上来自洛谷 以上来自洛谷 以上来自洛谷
解题思路
温馨提示
阅读能力较差的可以看视频教程(非本人,但制作不易,麻烦三连)。
正文
第一步一定是要下最中间的。
我:
(500,500)
(501,501)
地图(1 为我,0 为 AI,# 为空地):
1#
#1
AI 此时有三种选择:
两个 # 都不堵。
如此时:
AI:
(499,500)
(499,501)
那么我们便可以下成:
我:
(500,501)
(501,500)
赢得棋局。
只堵其中一个 #。
结论
先给出结论,当有一个形如:
???
#1#
#11
?##
不用考虑方向,我们就可以在一步之内取得胜利。
- 若此时是我们的回合。直接赢了没啥说的。
- 若此时是 AI 的回合。我们有左、下、右上三个能凑成 2 × 2 2\times 2 2×2 的地方,AI 只能堵两个,轮到我的回合还是赢。
证明
说完这个结论,我们来想一下只堵一个的情况。
容易发现 AI 堵左下还是右上是无所谓的,所以我们关注另一颗棋子的动向:
随便下。
如此时:
AI:
(499,499)
(500,501)
那么我们就可以:
我:
(502,501)
(502,502)
此时的地图:
0###
#10#
##1#
##11
已经构造出了我们想要的东西,赢。
与第一颗棋子相连(八连通)。
如此时:
AI:
(500,501)
(500,502)
那么我们可以:
我:
(499,501)
(501,500)
此时地图如下:
#1#
100
11#
若此时 AI 把左面和下面都堵上了,我们就去上面构造那个东西,如下:
AI:
(501,499)
(502,500)
我:
(498,501)
(498,502)
此时地图如下:
##11
##1#
#100
011#
#0##
已经构造出了我们想要的东西,赢。若 AI 没把左面和下面都堵上,直接在左面或下面一步获得胜利。
如:
AI:
(498,501)
(502,501)
我:
(500,499)
(501,499)
赢。
四联通还有三种方案,拓展到八连通只多了两种有效方案,都可以用类似的方法破解。
两个 # 都堵。
此时 AI 只有一种方案,我们只要继续往右下角放就行。
AI:
(500,501)
(501,500)
我:
(502,502)
(503,503)
接下来 AI 这步下完,我们的四个棋子如果中间两个没被堵就拿中间两个赢,下面两个没被堵就拿下面两个赢。若都被堵了去构造那个东西就行。
如:
AI:
(501,502)
(503,502)
我:
(503,504)
(504,504)
此时地图如下:
10###
010##
##1##
##011
####1
此时,胜利。
其余方法同。证毕。
AC Code
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int Maxn = 1e3 + 5;
int X1, Y1, X2, Y2;
int Chess_Board[Maxn][Maxn];
inline void work() {
cout << 500 << " " << 500 << endl;
cout << 501 << " " << 501 << endl;
Chess_Board[500][500] = 1;
Chess_Board[501][501] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (Chess_Board[500][501] && Chess_Board[501][500]) {
cout << 502 << " " << 502 << endl;
cout << 503 << " " << 503 << endl;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[501][502] && !Chess_Board[502][501]) {
cout << 501 << " " << 502 << endl;
cout << 502 << " " << 501 << endl;
exit(0);
} else if (!Chess_Board[502][503] && !Chess_Board[503][502]) {
cout << 502 << " " << 503 << endl;
cout << 503 << " " << 502 << endl;
exit(0);
} else if (Chess_Board[503][502]) {
cout << 503 << " " << 504 << endl;
cout << 504 << " " << 504 << endl;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[504][503]) {
cout << 504 << " " << 503 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[502][503] && !Chess_Board[502][504]) {
cout << 502 << " " << 503 << endl;
cout << 502 << " " << 504 << endl;
exit(0);
} else {
cout << 503 << " " << 505 << endl;
cout << 504 << " " << 505 << endl;
exit(0);
}
} else {
cout << 504 << " " << 503 << endl;
cout << 504 << " " << 504 << endl;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[503][504]) {
cout << 503 << " " << 504 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[503][502] && !Chess_Board[504][502]) {
cout << 503 << " " << 502 << endl;
cout << 504 << " " << 502 << endl;
exit(0);
} else {
cout << 505 << " " << 503 << endl;
cout << 505 << " " << 504 << endl;
exit(0);
}
}
} else {
if (!Chess_Board[500][501] && !Chess_Board[501][500]) {
cout << 500 << " " << 501 << endl;
cout << 501 << " " << 500 << endl;
exit(0);
} else if (Chess_Board[500][501] && Chess_Board[501][502]) {
cout << 499 << " " << 501 << endl;
cout << 501 << " " << 500 << endl;
Chess_Board[499][501] = 1;
Chess_Board[501][500] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[498][501] && !Chess_Board[498][502] && !Chess_Board[499][500] && !Chess_Board[498][500] && !Chess_Board[497][501] && !Chess_Board[497][502]) {
cout << 498 << " " << 501 << endl;
cout << 498 << " " << 502 << endl;
Chess_Board[498][501] = 1;
Chess_Board[498][502] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[499][502]) {
cout << 499 << " " << 502 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[499][500] && !Chess_Board[498][500]) {
cout << 499 << " " << 500 << endl;
cout << 498 << " " << 500 << endl;
exit(0);
} else {
cout << 497 << " " << 501 << endl;
cout << 497 << " " << 502 << endl;
exit(0);
}
} else if (!Chess_Board[500][499] && !Chess_Board[501][499]) {
cout << 500 << " " << 499 << endl;
cout << 501 << " " << 499 << endl;
exit(0);
} else {
cout << 502 << " " << 499 << endl;
cout << 502 << " " << 500 << endl;
exit(0);
}
} else if (Chess_Board[500][501] && Chess_Board[499][501]) {
cout << 501 << " " << 499 << endl;
cout << 500 << " " << 502 << endl;
Chess_Board[501][499] = 1;
Chess_Board[500][502] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[499][503] && !Chess_Board[500][503] && !Chess_Board[499][504] && !Chess_Board[500][504] && !Chess_Board[501][502] && !Chess_Board[501][503] && !Chess_Board[499][502]) {
cout << 499 << " " << 503 << endl;
cout << 500 << " " << 503 << endl;
Chess_Board[499][503] = 1;
Chess_Board[500][503] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[499][502]) {
cout << 499 << " " << 502 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[499][504] && !Chess_Board[500][504]) {
cout << 499 << " " << 504 << endl;
cout << 500 << " " << 504 << endl;
exit(0);
} else {
cout << 501 << " " << 502 << endl;
cout << 501 << " " << 503 << endl;
exit(0);
}
} else if (!Chess_Board[500][499] && !Chess_Board[501][499]) {
cout << 500 << " " << 499 << endl;
cout << 501 << " " << 499 << endl;
exit(0);
} else {
cout << 502 << " " << 500 << endl;
cout << 502 << " " << 501 << endl;
exit(0);
}
} else if (Chess_Board[501][500] && Chess_Board[501][499]) {
cout << 500 << " " << 501 << endl;
cout << 502 << " " << 500 << endl;
Chess_Board[500][501] = 1;
Chess_Board[502][500] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[503][500] && !Chess_Board[503][501] && !Chess_Board[502][499] && !Chess_Board[503][499] && !Chess_Board[504][500] && !Chess_Board[504][501] && !Chess_Board[502][501]) {
cout << 503 << " " << 500 << endl;
cout << 503 << " " << 501 << endl;
Chess_Board[503][500] = 1;
Chess_Board[503][501] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[502][501]) {
cout << 502 << " " << 501 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[502][499] && !Chess_Board[503][499]) {
cout << 502 << " " << 499 << endl;
cout << 503 << " " << 499 << endl;
exit(0);
} else {
cout << 504 << " " << 500 << endl;
cout << 504 << " " << 501 << endl;
exit(0);
}
} else if (!Chess_Board[500][502] && !Chess_Board[501][502]) {
cout << 500 << " " << 502 << endl;
cout << 501 << " " << 502 << endl;
exit(0);
} else {
cout << 499 << " " << 500 << endl;
cout << 499 << " " << 501 << endl;
exit(0);
}
} else if (Chess_Board[501][500] && Chess_Board[502][500]) {
cout << 500 << " " << 501 << endl;
cout << 501 << " " << 499 << endl;
Chess_Board[500][501] = 1;
Chess_Board[501][499] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[501][498] && !Chess_Board[502][498] && !Chess_Board[501][497] && !Chess_Board[502][497] && !Chess_Board[500][499] && !Chess_Board[500][498] && !Chess_Board[502][499]) {
cout << 501 << " " << 498 << endl;
cout << 502 << " " << 498 << endl;
Chess_Board[501][498] = 1;
Chess_Board[502][498] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[502][499]) {
cout << 502 << " " << 499 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[501][497] && !Chess_Board[502][497]) {
cout << 501 << " " << 497 << endl;
cout << 502 << " " << 497 << endl;
exit(0);
} else {
cout << 500 << " " << 499 << endl;
cout << 500 << " " << 498 << endl;
exit(0);
}
} else if (!Chess_Board[500][502] && !Chess_Board[501][502]) {
cout << 500 << " " << 502 << endl;
cout << 501 << " " << 502 << endl;
exit(0);
} else {
cout << 499 << " " << 500 << endl;
cout << 499 << " " << 501 << endl;
exit(0);
}
} else if (Chess_Board[500][501] && Chess_Board[499][502]) {
cout << 500 << " " << 502 << endl;
cout << 501 << " " << 502 << endl;
Chess_Board[500][502] = 1;
Chess_Board[501][502] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[500][499] && !Chess_Board[499][499] && !Chess_Board[501][500] && !Chess_Board[501][499] && !Chess_Board[500][498] && !Chess_Board[499][498] && !Chess_Board[499][500]) {
cout << 500 << " " << 499 << endl;
cout << 499 << " " << 499 << endl;
Chess_Board[500][499] = 1;
Chess_Board[499][499] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[499][500]) {
cout << 499 << " " << 500 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[501][500] && !Chess_Board[501][499]) {
cout << 501 << " " << 500 << endl;
cout << 502 << " " << 499 << endl;
exit(0);
} else {
cout << 500 << " " << 498 << endl;
cout << 499 << " " << 498 << endl;
exit(0);
}
} else if (!Chess_Board[502][502] && !Chess_Board[502][503]) {
cout << 502 << " " << 502 << endl;
cout << 502 << " " << 503 << endl;
exit(0);
} else {
cout << 500 << " " << 503 << endl;
cout << 501 << " " << 503 << endl;
exit(0);
}
} else if (Chess_Board[501][500] && Chess_Board[502][499]) {
cout << 500 << " " << 499 << endl;
cout << 501 << " " << 499 << endl;
Chess_Board[500][499] = 1;
Chess_Board[501][499] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[500][502] && !Chess_Board[501][502] && !Chess_Board[500][503] && !Chess_Board[501][503] && !Chess_Board[502][501] && !Chess_Board[502][502] && !Chess_Board[500][501]) {
cout << 500 << " " << 502 << endl;
cout << 501 << " " << 502 << endl;
Chess_Board[500][502] = 1;
Chess_Board[501][502] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[500][501]) {
cout << 500 << " " << 501 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[502][501] && !Chess_Board[502][502]) {
cout << 502 << " " << 501 << endl;
cout << 502 << " " << 502 << endl;
exit(0);
} else {
cout << 500 << " " << 503 << endl;
cout << 501 << " " << 503 << endl;
exit(0);
}
} else if (!Chess_Board[500][498] && !Chess_Board[501][498]) {
cout << 500 << " " << 498 << endl;
cout << 501 << " " << 498 << endl;
exit(0);
} else {
cout << 499 << " " << 499 << endl;
cout << 499 << " " << 500 << endl;
exit(0);
}
} else if (Chess_Board[501][500]) {
if (!Chess_Board[500][502] && !Chess_Board[501][502] && !Chess_Board[500][503] && !Chess_Board[501][503] && !Chess_Board[502][501] && !Chess_Board[502][502] && !Chess_Board[500][501]) {
cout << 500 << " " << 502 << endl;
cout << 501 << " " << 502 << endl;
Chess_Board[500][502] = 1;
Chess_Board[501][502] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[500][501]) {
cout << 500 << " " << 501 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[500][503] && !Chess_Board[501][503]) {
cout << 500 << " " << 503 << endl;
cout << 501 << " " << 503 << endl;
exit(0);
} else {
cout << 502 << " " << 501 << endl;
cout << 502 << " " << 502 << endl;
exit(0);
}
} else {
cout << 499 << " " << 500 << endl;
cout << 499 << " " << 501 << endl;
Chess_Board[499][500] = 1;
Chess_Board[499][501] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[500][501]) {
cout << 500 << " " << 501 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[500][499] && !Chess_Board[499][499]) {
cout << 500 << " " << 499 << endl;
cout << 499 << " " << 499 << endl;
exit(0);
} else {
cout << 498 << " " << 500 << endl;
cout << 498 << " " << 501 << endl;
exit(0);
}
}
} else {
if (!Chess_Board[502][500] && !Chess_Board[502][501] && !Chess_Board[503][500] && !Chess_Board[503][501] && !Chess_Board[501][502] && !Chess_Board[502][502] && Chess_Board[501][500]) {
cout << 502 << " " << 500 << endl;
cout << 502 << " " << 501 << endl;
Chess_Board[502][500] = 1;
Chess_Board[502][501] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[501][500]) {
cout << 501 << " " << 500 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[503][500] && !Chess_Board[503][501]) {
cout << 503 << " " << 500 << endl;
cout << 503 << " " << 501 << endl;
exit(0);
} else {
cout << 501 << " " << 502 << endl;
cout << 502 << " " << 502 << endl;
exit(0);
}
} else {
cout << 500 << " " << 499 << endl;
cout << 501 << " " << 499 << endl;
Chess_Board[500][499] = 1;
Chess_Board[501][499] = 1;
cin >> X1 >> Y1 >> X2 >> Y2;
Chess_Board[X1][Y1] = 1;
Chess_Board[X2][Y2] = 1;
if (!Chess_Board[501][500]) {
cout << 501 << " " << 500 << endl;
cout << 114 << " " << 514 << endl;
exit(0);
} else if (!Chess_Board[499][500] && !Chess_Board[499][499]) {
cout << 499 << " " << 500 << endl;
cout << 499 << " " << 499 << endl;
exit(0);
} else {
cout << 500 << " " << 498 << endl;
cout << 501 << " " << 498 << endl;
exit(0);
}
}
}
}
cout << flush;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
work();
return 0;
}
怪不得通过率才 5 % 5\% 5%。(2024.1.27)