[BZOJ3609]-[Heoi2014]人人尽说江南好-神分析+博弈

版权声明:转载嘛....也不是不可以(故作沉思),记得带上me的ID啊qwq https://blog.csdn.net/Izumi_Hanako/article/details/80189596

说在前面

刷博弈……


题目

BZOJ3609传送门

题目大意

公平组合游戏
给出 n 堆石子,每堆石子初始都只有一个
可以合并两堆石子,得到一堆石子,石子个数等于原来两堆石子数之和
对于双方玩家,唯一允许的操作是:将两堆石子合并,且合并之后石子个数不能超过 m
询问是否先手必胜
范围:n,m109
数据组数:T10

输入输出格式

输入格式:
第一行一个整数 T ,表示数据组数
接下来 T 行,每行两个整数 n,m,含义如题

输出格式:
对于每组数据,输出一行:
如果先手必胜输出 0,不然输出 1


解法

(感觉比较神的一道题,看了lych的题解,这里只是整理思路)

首先可以确定,只有最终的合并次数,对答案有影响
偶数次先手必败,奇数次先手必胜

那么对于任意一个初始局面,先手都希望合并奇数次,而后手都希望合并偶数次
结论是,双方一定都可以达到合并次数最多的局面
合并次数最多的情况,显然就是石子堆都变成了这样:m,m,,nmodm

证明:假设这样的合并次数是偶数,那么后手一定可以达到这个局面

  • 首先如果nm那么显然只能是这个局面
  • 考虑现在石子个数是 m+1(此时m为奇数,偶数情况类似),首先先手肯定会合并两个石子,称这一堆为「大堆」,然后后手会将一堆石子合并到「大堆」里。
    接下来,如果先手合并了两个石子,后手就把这两个石子和最大的一堆合并。不然的话他们都会将石子向「大堆」合并。每次后手操作之后,大堆总是奇数个,所以到达 (m,1) 局面时,后手胜

同理,对于后手,可以推广到 (m,3) 局面,(m,5) 局面
对于先手,也可以用类似的证明。比如对于 m+2 颗石子,先手始终将石子向大堆合并,最后一步要么是 (m,1,1),要么是 (m1,2,1),然后可以得出先手必胜
然后也可以推广到m,m,m的局面

于是这题就做完了


下面是代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std ;

int T ;
long long N , M ;

int main(){
    scanf( "%d" , &T ) ;
    while( T -- ){
        scanf( "%lld%lld" , &N , &M ) ;
        long long t = ( N / M ) * ( M - 1 ) + ( N %M ? N %M - 1 : 0 ) ;
        if( t&1 ) puts( "0" ) ;
        else puts( "1" ) ;
    }
}
阅读更多

没有更多推荐了,返回首页