POJ 2311 博弈论 特详细...

题意是一张纸 n*m 每人切一刀 1*1 的赢  切了不扔掉

----------

默认2 2  / 2 3 / 3 2 都已经失败了

(1 n)这里没进行初始化...  题目里没给  代码里就没达到

(严格的说其实按说都应该拓展成……的)

由异或知, 如果切完之后是两个必败的状态(0和0) ,那么就是当前状态可以达到0 ,mex一下就不会拿到0,所以当前应该是必胜的状态。

如果切完之后能达到两个一样必胜状态(如2 4 2 4 ),从运算上说可以到达0,从理论上说,我切完之后对手只能捣鼓两个必胜态,必胜态的定义是只能达到必败态,他给了两个必败态,我把剩下的必胜态也变成了两个必败态,所以最后还是对手达到必败。

感谢zj爸爸在吃饭的时候让我从1 1 推到2 2 /2 3/2 4 /2 5/2 6 /2 7各种然后稍微明白了一点。

如果这个状态分解下去如2 4 只能达到两个必败态则它必胜,因为对手无路可走。

2 7 2 6 什么的都是。

 但是如果死切,只能切出一个必胜和一个必败,是没用的,对手去切必胜给你留下三个必败。

必须要两个必胜和两个必败才可以。

使用异或可以做到。

int gao(int x, int y)这里只是跑一次用到的。

for (int i = 2; i < x - 1; i++) {
        int tmp = sg[i][y] ^ sg[x - i][y];

比如要走x y 那么x固定不动可以怎么切,罗列一下。

就是第一个for循环。 比如7 7  那么试一下从2 7 到7 7 

(2 7 又不是单纯的2 7 肯定是4  7 和3 7 )

状态是(x-i)以及i

能达到的所有状态记为tmp,如果有一个有幸达到了是0 的tmp,这个状态就是必胜态。

(在 7 7  固定2 7 到7 7和7 2 到7 7 里面所有的状态都记录过了。)

所以要写两个for循环,每个for循环里面手动算一下。

记录状态的tmp不用bool,但是visit完全可以用bool类型来初始化。

(下面的 没初始化之前都是0)

#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 205
int n, m;
int sg[maxn][maxn];
bool visit[maxn];
int getsj(int x,int  y) {
	int tmp = 0;
	///cout << "x y " << x << y << endl;
	// ....  这里应该是x-i 和y-i
	//因为加起来是x-i +i= x
	//x只能分解成这样呀. 
	//...  过来的时候最好记录一下状态吧
	//... 代码实现能力好差 
	memset(visit, 0, sizeof(visit));
	for (int i = 2; i <  x-1; i++) {	
		tmp = sg[i][y] ^ sg[x-i][y];
		visit[tmp] = 1;
	}
	for (int i = 2; i < y-1; i++) {
		tmp = sg[x][i] ^ sg[x][y-i];
		visit[tmp] = 1;
	}
	
	//****** 这里要写成0 ,不然不能记录必败态(为0时候的形态)
	//.... 
	for (int i = 0; i <= maxn-1; i++) {
		if (visit[i] != 1)//==0 的话 没访问过
		{
			//cout << i << endl;
			return sg[x][y]=i;
		}
	}
	return 0;
}
int main() {

	for (int i = 1; i <= maxn-1; i++) {	sg[1][i] = 1; sg[i][1] = 1;}
	for (int i = 2; i <= maxn-1; i++) {
		for (int j = 2; j <= maxn-1; j++) {
			if ((i == 2 && j == 3) || (i == 3 && j == 2) || (i == 2 && j == 2) || (i == 3 && j == 3))
				sg[i][j] = 0;
			//千万要有转移的状态..
			//3 3 是必败的 因为不能到达两个必胜的或者必败的状态
			else 
			sg[i][j] = getsj(i,j);
		}
	}
		while (cin >> n >> m) {
			if (sg[n][m] == 0)puts("LOSE");
			else puts("WIN");
		}

	return 0;
}

要特别注意的有两点:

(1) runtime error的时候  maxn那边达到了vs不给说错,maxn 105到不了

(2)...  x-i 和i  写的时候写慢一点 每一行都想一下

代码参考 https://blog.csdn.net/Yukizzz/article/details/52076075

...........

从开始看这题,还跟zj讨论了,还看了。。  别人的代码最后

还是。。。

。。。。。。

代码习惯不好哦。以前就算我是写了一下午的bfs 最后也只看着别人的找不同,……

其实没用的

自己看一天和陷入找不同都不好

这两天 的题目大概是自己不熟悉吧  最后一直找不同找不同

猜你喜欢

转载自blog.csdn.net/StrongerIrene/article/details/81270519