题目链接:点击打开链接
这道题目是巴什博弈,对博弈论我也是理解的比较浅,还得多多学习,下面粘贴别人的一段题解,来补充我自己的知识匮乏,
(一)巴什博弈:
只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。因此我们发现了如何取胜的法则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下(m+1)的倍数,就能最后获胜。
题目分析: 这是一个典型的巴什博弈,只要m%(n+1)==0就是后手赢。难点在于先手赢的情况是要输出所有可能的第一次出价情况。需要判断n是否大于等于m,如果n>=m则m~n的所有数都是符合情况的,而m>n时,第一次取的是m除以(n+1)的余数,因为只有让后手者保持(n+1)的倍数才能先手必胜。代码:
#include<stdio.h>
int main()
{
int m,n,i;
while(~scanf("%d%d",&m,&n))
{
if(m%(n+1)==0)
printf("none\n");
else
{
if(n>=m)
{
for(i=m; i<=n-1; i++)
printf("%d ",i);
printf("%d\n",n);
}
else
printf("%d\n",m%(n+1));
}
}
return 0;
}
这个代码是我自己按照它的那个意思写的,结果ac了,我反正理解的还是不够深刻,以后还是要多多总结(关于博弈)。
还有一道巴什博弈的题目(题目链接:点击打开链接)
比较简单,代码就不附了。
题目链接:点击打开链接
代码:
#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
long long q[100000];
int main()
{
long long a,i;
while( ~scanf("%I64d",&a))
{
memset(q,0,sizeof(q));
if(a<=2)
printf("0\n");
else
{int j=0;
for( i=1; i*i<=a; i++)
if(a%i==0)
{
q[j++]=i;
q[j++]=a/i;
}
sort(q,q+j);
for(i=0; i<j; i++)
{
if(q[i]>2){ printf("%I64d\n",q[i]-1);
break;}
}
}
}
return 0;
}
这个题目有一个坑点,就是L的取值范围,还有题里面没有给出数据范围,这一点比较坑,最后还得优化一下。