P9898 『PG2』猪棋 题解 博弈论

『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 1x1,y1,x2,y21000,你其次需要保证没人曾在 ( 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),1x1,y1,x2,y21000,如果此时交互库获胜判定结束且你输了,否则判定棋盘上是否已经有 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 6x,y994 你将获得 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)

  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值