推导:https://blog.csdn.net/qust1508060414/article/details/52194676
一.巴什博弈 Bash Game
描述:
只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取1个,最多取b个。最后取光者得胜。
方案:
n%(1 + m) != 0 先手赢
else 后手赢
应用:
1.经典问法 hdu1846
2.累加得n
(1)两个人轮流捐款,每次捐款数不超过m,最先使捐款数大于等于n的获胜 hdu2188
(2) 两人轮流写数字,假设上一轮写的数字是X,那么下一个玩游戏的人应该写一个数字Y,使得1<=Y-X<=k,先写一个>=N的数字的人将输掉游戏(第一轮的数字范围为【1,k】) hdu4764
注意此题是大于等于n的输
可转化为,有n-1个石子的经典问法
while(cin>>k>>m)
{
if(k==0&&m==0)break;
if((k-1)%(m+1)==0)cout<<"Jiang"<<endl;
else cout<<"Tang"<<endl;
}
(3)底价为0,两个人轮流开始加价,不过每次加价的幅度要在1~N之间,当价格大于或等于田地的成本价 M 时,主办方就把这块田地卖给这次叫价的人,Lele先开始加价,请问,第一次加价的时候,Lele要出多少才能保证自己买得到这块地呢? hdu2149
先手赢 即先手取完之后,剩余石子数使后手必败,即(n-ans)%(m+1)==0 即ans=n%(m+1);
如果ans
属于1~m 则先手可以赢 否则就不能赢
另外需要注意的是,此题的m可以大于n
那么有多个答案 分别为 n~m
while(cin>>n>>m)
{
ans=n%(m+1);
if(m>=n)
{
for(int i=n;i<=m;i++)
{
cout<<i;
if(i!=m)cout<<" ";
}
cout<<endl;
}
else if(ans>=1&&ans<=m)
{
cout<<ans<<endl;
}
else cout<<"none"<<endl;
}
3.变形
(1)有一堆石子共有N个。A B两个人轮流拿,A先拿。每次只能拿1,3,4颗,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N,问最后谁能赢得比赛。例如N = 2。A只能拿1颗,所以B可以拿到最后1颗石子。 51Nod1067
scanf("%d",&t);
while(t --)
{
int n;
scanf("%d",&n);
if(n%7==2||n%7==0)printf("B\n");
else printf("A\n");
}
(2)有一堆石子共有N个。A B两个人轮流拿,A先拿。每次拿的数量只能是2的正整数次幂,比如(1,2,4,8,16…),拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N,问最后谁能赢得比赛。例如N = 3。A只能拿1颗或2颗,所以B可以拿到最后1颗石子。(输入的N可能为大数) 51Nod1068
是3的倍数时,B赢
N是大数,所以不直接用N%3,而是把N每一位上的数相加,用得到的和%3
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int sum=0;
string s;
cin>>s;
for(int i=0;i<s.length();i++)
sum+=s[i]-'0';
printf("%c\n",sum%3?'A':'B');
}
return 0;
}