白书-poj2311 Cutting Game(SG函数)

本文探讨了一个给定w*h格纸的程序竞赛题目,通过分析切割策略,确定了在特定条件下玩家的胜负情况。文章深入讲解了如何使用SG函数解决此类问题,并分享了一段实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

给定w*h的格纸,轮流沿格线切割,

当前有好几块格纸的,可以挑任意一块切,

先切出一个1*1方格的一方获胜,

给定w和h(2<=w,h<=200),问谁必胜

思路来源

《挑战程序竞赛》第二版

题解

注意到如果切割出了1*h或者w*1的纸张

则下一步对手一定会切这一张,使己方必败

所以切的时候,只考虑在大于等于2的行和列里转移

剩下答案就是两个子局面的异或了,SG函数常规操作

心得

补白书.jpg

马上就要期末复习了,有点恋恋不舍,什么都想刷一点

SG函数这个set的写法挺好的,也不用开个大数组每次清空vis

而且注意到sg函数的值只和初始局面有关,与从什么状态转移来无关,

故只需memset一次dp数组,之后就利用现成结果就可以了

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
int r,c;
int dp[205][205];
int sg(int w,int h) 
{
	if(~dp[w][h])return dp[w][h];
	set<int>q;
	for(int i=2;w-i>=2;++i)
	q.insert(sg(i,h)^sg(w-i,h));
	for(int j=2;h-j>=2;++j)
	q.insert(sg(w,j)^sg(w,h-j));
    int res=0;
	while(q.count(res))res++;
	return dp[w][h]=res;
}
int main()
{
	memset(dp,-1,sizeof dp);
	while(~scanf("%d%d",&r,&c))
	puts(sg(r,c)?"WIN":"LOSE");
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小衣同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值