题意:
两个人玩游戏(博弈),有一个n*m大小的方阵,有k个点,每个点上有数量不定的水晶,两人轮流移动,每次移动可以把一个位置上任意数量(大于0) 的水晶移动到这个位置的上一格或者右一格,不能移动到边界外,轮到谁没有可操作的水晶的话谁就输。
整个方阵上有两种特殊的位置,数量不定。一种叫 Meditations ,这种位置上的水晶挪动的时候,假如你想往上移动m个,那么这个特殊位置会同时往右移动m个,如果这种位置在边界的话,你挪动m个,它会自动把m变成2*m;
另一种叫pollutant sources,当你把水晶挪动到这些点时,它只会留下一半(向下取整)的水晶。
题中给了一个奇怪的式子:
意思是对任意一对Meditations点和pollutant sources点,保证上式是奇数。
其实这个式子就是两个点的横坐标距离+纵坐标距离。
题中保证(n,m)处有一个pollutant sources点,(n-1,m)处有一个Meditations点。
思路:
首先如果不考虑这两种特殊点的存在的话,就是一个阶梯博弈,向上或向右的终点就是(n,m)这一点,只需把所有到终点的距离为奇数的点处的水晶数量异或起来就行了。
但是有这两种点的存在 ,我们还是要考虑一下的。
因为终点处有一个pollutant sources点,而所有的Meditations点到终点的距离为奇数,又因为所有pollutant sources点到Meditations点的距离为奇数,所以两个pollutant sources点之间的距离为偶数,即所有pollutant sources点到终点的距离是偶数,和异或没关系,去掉pollutant sources点的影响。
对于任一Meditations点,因为这种点到终点距离是奇数,当在这个点挪了t个水晶,相当于给偶数点上加了2*t个水晶,不论下一个人做了何种操作,我总可以在我的回合把t个水晶挪回到奇数堆,那么当前局面对于我的胜负状态没有影响,所以Meditations点的影响也可以去掉。
所以这题就是一个直接的阶梯博弈。
#include<cstdio>
using namespace std;
int n,m,T,k,x,y,w;
int main()
{
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&k);
int ans=0,t=n+m;
while(k--){
scanf("%d%d%d",&x,&y,&w);
if((t-x-y)&1)ans^=w;
}scanf("%d",&k);while(k--)scanf("%*d%*d");
scanf("%d",&k);while(k--)scanf("%*d%*d");///%*d表示只输入%d类型的数据但是不给变量赋值
if(ans)
printf("win\n");
else
printf("lose\n");
}return 0;
}