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

说在前面

刷博弈……


题目

BZOJ3609传送门

题目大意

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

输入输出格式

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

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


解法

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

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

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

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

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

同理,对于后手,可以推广到 ( m , 3 ) 局面, ( m , 5 ) 局面
对于先手,也可以用类似的证明。比如对于 m + 2 颗石子,先手始终将石子向大堆合并,最后一步要么是 ( m , 1 , 1 ) ,要么是 ( m 1 , 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" ) ;
    }
}

猜你喜欢

转载自blog.csdn.net/izumi_hanako/article/details/80189596