巴什博弈
问题描述:有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至 少取一个,最多取m个。最后取光者得胜。 在已知n和m的情况 下请你判断是先手取胜出还是后手取胜出。
问题解析:对这一堆中的n个物品我们可将其分成多个小堆,每小堆m+1个物品。剩余:n%(m+1)
n%(m+1) |
1 | m |
1 | m |
... | ... |
... | ... |
... | ... |
1 | m |
只需判断剩余的物品个数是否为0即可。
当剩余物品不为0,即n%(m+1)!=0,而n%(m+1)<m+1,所以先手可以直接取完剩余的部分。对于每小堆由于规定只能取1~m个,所以此时后手不能取完这一小堆,而又不能不取。所以后手只能取走第一小堆中的一部分。 由于后手取走了第一小堆中的一部分,而整个这一小堆右只有m+1个,所以无论后手取走了多少,先手都能取完剩余的部分。
n%(m+1) | 先手取完这一部分 | |
后手取走一部分 | m+1 | 先手取走剩余的部分 |
后手取走一部分 | m+1 | 先手取走剩余的部分 |
后手取走一部分 | ... | 先手取走剩余的部分 |
后手取走一部分 | ... | 先手取走剩余的部分 |
后手取走一部分 | ... | 先手取走剩余的部分 |
后手取走一部分 | m+1 | 先手取走剩余的部分 |
反之n%(m+1)=0:
0 | ||
先手取走一部分 | m+1 | 后手取走剩余的部分 |
先手取走一部分 | m+1 | 后手取走剩余的部分 |
先手取走一部分 | ... | 后手取走剩余的部分 |
先手取走一部分 | ... | 后手取走剩余的部分 |
先手取走一部分 | ... | 后手取走剩余的部分 |
先手取走一部分 | m+1 | 后手取走剩余的部分 |
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
int n,m,mod;
cin>>n>>m;
mod=n%(m+1);
if(mod>0)
cout<<"first win"<<endl;
else
cout<<"last win"<<endl;
return 0;
}
import java.util.*;
public class BashGame {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int t=sc.nextInt();//测试组数
while(t-->0){
int n=sc.nextInt();
int m=sc.nextInt();
int mod=n%(m+1);
if(mod>0)
System.out.println("first win");
else
System.out.println("second win");
}
}
}