P4101 人人尽说江南好

题目链接:P4101 人人尽说江南好

算法分析

无论怎么操作,最终合并的次数为奇数,则先手胜,否则先手败。先假设一种合并方案,双方尽量合并成 m m m,然后再从1开始合并。这样总共的合并次数为: c n t = n / m ∗ ( m − 1 ) + ( ( n % m ) ? ( n % m − 1 ) : 0 ) cnt = n/m*(m-1)+((n \% m)?(n\% m-1):0) cnt=n/m(m1)+(n%m)?(n%m1):0。我们称此为套路。

如果此时cnt为奇数,我们知道先手胜。先手必胜,肯定会按照套路走,如果后手不按照套路出牌呢?讨论下:

最大堆石子数 < = m − 2 <=m-2 <=m2

  1. 后手将1和最大堆合并,这是按照套路走的,先手继续按照套路走即可。

  2. 后手将两个1合并,得到一个为2的堆,先手将这个为2的堆和最大堆合并,将后手的思路拉回到套路上来。

最大堆石子数等于 m − 1 m-1 m1

  1. 后手将1和最大堆合并,没有区别。

  2. 后手合并两个1,得到一个为2的堆,先手将1合并到最大堆,此时最大堆已满。后面又可以按照套路来了。

无论怎么操作,先手都可以稳住套路,保证最后的合并次数不变。

后手胜的情况也是一样的。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define ll long long 
ll n, m, cnt;
int main()
{
	int T;
	scanf("%d", &T);
	while (T--)
	{
		scanf("%lld%lld", &n, &m);
		cnt = n / m * (m - 1) + ((n % m) ? (n % m - 1) : 0); // ?:运算符得用括号,否则错  
		if (cnt & 1) printf("0\n");	else printf("1\n");
	}
	return 0;
}

反思与总结

  1. 在用条件运算符时,整体得加括号,否则错误。

  2. 该题思路:确定一种方案,证明其他方案最终和该方案等效。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值