本文目录一览:
- 1、C++编程, 取石子游戏. 一堆石21个石子. 玩家1跟玩家2轮流取1-4的石子. 取走最后一个石子的玩家胜出.
- 2、北理工C语言【游戏】取石子
- 3、C语言捡石子游戏
- 4、杭电acm 第2516题 取石子 游戏 的答案
- 5、取石子游戏求答案!!
- 6、取石子游戏怎么定胜?
C++编程, 取石子游戏. 一堆石21个石子. 玩家1跟玩家2轮流取1-4的石子. 取走最后一个石子的玩家胜出.
第一个取石子的人一定会取胜,请参考以下策略:
第一个人取1颗石子;
第二个人取x(1=x=4)颗石子;
第一个人取(5-x)颗石子,即始终保证他所取的石子数与第二个人刚才取的石子数,相加为5;
重复步骤2,3直至石子取完,第一个人始终将获得最后一颗石子。
北理工C语言【游戏】取石子
#includestdio.h
#includeconio.h
int main(void)//也就是a或者b有一项为2或者1时,有必胜方法.
{
int i, T, a[50] = { 0 }, b[50] = { 0 }, c[50] = { 0 };
scanf("%d", T);
for (i = 0; i T; ++i)
{
scanf("%d", a[i]);
scanf("%d", b[i]);
if (a[i] == 1 || a[i] == 2 || b[i] == 1 || b[i] == 2)
c[i] = 1;
}
for (i = 0; i T; ++i)
{
if (c[i] == 1)
printf("YES\n");
else
printf("NO\n");
}
getch();
return 0;
}
C语言捡石子游戏
可以用递归来做,
假设 有A,B两堆石子。 A的数量是x,B的是y
递归的出口是3个状态。
1:其一等于1,另一个等于2 (输)
2:其一等于1,另一个2 (赢)
3:其一等于2,另一个1 (赢)
另外,只需要定义操作了, 操作只能是两者之一。 其一:(de_both)两堆都减去同一数字的石子。另外一个(de_one)就是人选一堆,拿掉任意个数的石子。
递归过程如下;
void simulate(int a,int b)
{
switch(state)
{
case 1:
you lose;
case 2:
break;
case 3:
you win;
}
if(abs(a,b)=1) /*这时候一定能赢*/
{
de_both(min(a,b)-1); /*两边都取走两者中最小数-1个石子,形成状态1的形式*/
}
else
{
de_one(random); /*这里的random只需要不使两者之差=1即可*/
}
simulate(a,b);
}
杭电acm 第2516题 取石子 游戏 的答案
#includeiostream
#includefstream
#includealgorithm
using namespace std;
int Fib[44];
int main()
{
int n;
Fib[0]=2;Fib[1]=3;
for(int i=2;i44;i++)
Fib[i]=Fib[i-1]+Fib[i-2];
while(cinnn){
if(std::binary_search(Fib,Fib+44,n))
cout"Second win"endl;
else
cout"First win"endl;
}
return 0;
}
/*
博弈论
解题分析:
当n为1的时候是输出first,n为2的时候输出second,
3的时候也是输出second,当n为4的时候,第一个人想获胜就必须先取
一个,这是剩余的石子数为3,此时无论第二个人如何取,第一个人都
能够赢,当n为5的时候,first不可能获胜,因为他取2时,second直接
取掉剩余的3个,取1时,second也是取1,这样就演变为n为3的时候了,
所以n为5时候,输出的是second ,当n为6的时候,first只要取掉1个,
就可以让局势变为n为5的时候,输出的是first,n为7的时候,first取掉
2个,又可以变为5的时候,所以也是输出first,n为8的时候,当first
取1个时候,局势变为7的时候,第二个人可以赢,取2时候,变为n为6的时
候,也是第二个人赢,取三个时候,second直接取掉剩余的5个,所以,n为
8的时候,是输出second。从上面可以看出,n为2,3,5,8时,这些都是输
出second,也就是说这些就是必败点,仔细的人会发现这些满足斐波那契数
的规律,可以推断13也是一个必败点,也就是说,只要是斐波那契数,都是
必败点,输出的就是second,所以,我们可以利用斐波那契数数的公式:
fib[i]=fib[i-1]+fib[i-2],只要n是斐波那契数,那就输出second,所以有
if(n==fib[i])
printf(“Second win\n”);
else
printf(“First win\n”);
*/
取石子游戏求答案!!
楼主你好:
我不是高手,以下是我在互联网上给你找的,对你绝对有帮助,算是公式吧,
建议你在参考资料里查看原文。
有三堆各若干个物品,两个人轮流从某一堆取任意多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
这种情况最有意思,它与二进制有密切关系,我们用(a,b,c)表示某种局势,首先(0,0,0)显然是奇异局势,无论谁面对奇异局势,都必然失败。第二种奇异局势是(0,n,n),只要与对手拿走一样多的物品,最后都将导致(0,0,0)。仔细分析一下,(1,2,3)也是奇异局势,无论对手如何拿,接下来都可以变为(0,n,n)的情形。
计算机算法里面有一种叫做按位模2加,也叫做异或的运算,我们用符号(+)表示这种运算。这种运算和一般加法不同的一点是1+1=0。先看(1,2,3)的按位模2加的结果:
1 =二进制01
2 =二进制10
3 =二进制11 (+)
———————
0 =二进制00 (注意不进位)
对于奇异局势(0,n,n)也一样,结果也是0。
任何奇异局势(a,b,c)都有a(+)b(+)c =0。
如果我们面对的是一个非奇异局势(a,b,c),要如何变为奇异局势呢?假设 a b c,我们只要将 c 变为 a(+)b,即可,因为有如下的运算结果: a(+)b(+)(a(+)b)=(a(+)a)(+)(b(+)b)=0(+)0=0。要将c 变为a(+)b,只要从 c中减去 c-(a(+)b)即可。
例1:(14,21,39),14(+)21=27,39-27=12,所以从39中拿走12个物体即可达到奇异局势(14,21,27)。
例2:(55,81,121),55(+)81=102,121-102=19,所以从121中拿走19个物品就形成了奇异局势(55,81,102)。
例3:(29,45,58),29(+)45=48,58-48=10,从58中拿走10个,变为(29,45,48)。
例4:我们来实际进行一盘比赛看看:
甲:(7,8,9)-(1,8,9)奇异局势
乙:(1,8,9)-(1,8,4)
甲:(1,8,4)-(1,5,4)奇异局势
乙:(1,5,4)-(1,4,4)
甲:(1,4,4)-(0,4,4)奇异局势
乙:(0,4,4)-(0,4,2)
甲:(0.4,2)-(0,2,2)奇异局势
乙:(0,2,2)-(0,2,1)
甲:(0,2,1)-(0,1,1)奇异局势
乙:(0,1,1)-(0,1,0)
甲:(0,1,0)-(0,0,0)奇异局势
甲胜。
对于本次普及组“取石子游戏”来说,
19 010011
7 000111
5 000101
3 000011
010010 (18)10
50-18=32
所以第1次只能在第5堆石子中取32粒,使得取出32粒后为奇异局势,即异或运算结果为0。
取石子游戏怎么定胜?
只有一堆时,无论有多少,先取者都可以一次性全部取走,所以必胜。
(1,1)时,显然先取者必败。
(1,2)时,先取者必胜,他可以在2那一堆中取1个,于是变成(1,1),但这成为上一种情况了,于是接下来取的人必败,亦即先取者必胜。
(1,3)时,先取者必胜。他可以在3那一堆中取2个,于是变成(1,1)。
(2,2)时,先取者必败。他在任何一堆中取1个,对方随即在另一堆中取1个,即变成(1,1);如果他取走一堆中的全部石子,对方即取走另一堆中的全部石子。
(2,3)时,先取者必胜。他可以在3那一堆中取1个,于是变成(2,2)。
(3,3)时,先取者必败。他取走任一堆中的1,2或3个,就变成了以上讨论过的情形。
(1,1,1)时,先取者必胜。他取走任一堆,就变成了(1,1)。
(1,1,2)时,先取者必胜。他取走2那一堆,就变成了(1,1)。
(1,1,3)时,先取者必胜。他取走3那一堆,就变成了(1,1)。
(1,2,2)时,先取者必胜。他取走1那一堆,就变成了(2,2)。
(1,2,3)时,先取者必败。分析如下:
他先取1那一堆,则变为(2,3),由上面的分析,对手必胜。
他从2那一堆中取1个,就变成了(1,1,3),对手可以将3那一堆全部取走,变成了(1,1),于是必胜。
他将2那一堆全部取走,就变成了(1,3),对手必胜。
他从3那一堆中取1个,就变成了(1,2,2),对手必胜。
他从3那一堆中取2个,就变成了(1,2,1),对手必胜。
他将3那一堆全部取走,就变成了(1,2),对手必胜。
这些胜负有什么规律呢?我们可以将每堆的数转换成二进制,然后看每一位上所有堆里的1的个数总和:
必胜情况:(n) (1,2)(1,3)(2,3) (1,1,1)(1,1,2)(1,2,2)
必败情况: (1,1)(2,2)(3,3) (1,2,3)
化为二进制:
必胜情况:
(n)只有1堆:……(反正每位只要有1肯定只有1个)
(1,2):1,10
列成竖式:
01
10
个位上只有1个1,“十位”(因为是二进制所以叫十位不妥,这里为了方便说明暂且使用,下同)上也只有1个1。
(1,3):1,11
列成竖式:
01
11
个位上有2个1(1的1个,3的1个),十位上有1个1。
(2,3):10,11
个位上有1个1,十位上有2个1。
(1,1,1):1,1,1
个位上有3个1。
(1,1,2):1,1,10
个位上有2个1,十位上有1个1。
(1,1,3):1,1,11
个位上有3个1,十位上有1个1。
(1,2,2):1,10,10
个位上有1个1,十位上有2个1。
必败情况:
(1,1):1,1
个位上有2个1。
(2,2):10,10
十位上有2个1。
(3,3):11,11
个位上有2个1,十位上也有2个1。
(1,2,3):1,10,11
个位上有2个1,十位上也有2个1。
下面分析一下这些情况。
先看必败情形。容易发现,所有的必败情形,都是所有的数位上都有偶数个1。
下看必胜情形。我们发现,出现了两种情况:
1.只有1位上有奇数个1,如(1,3)(2,3)(1,1,1)(1,1,2)(1,2,2)。而先取者取走该位上的1,所有的位上就都变成了偶数个1,而这时后取者变成了先取者。
2.有若干位上都是奇数个1,如(n)(1,2)(1,1,3)。先取者取(不一定取走哪位)后,所有的位上也都变成了偶数个1。后取者变成了先取者。
以上两种情况,都是将后取者逼至必败情况从而取胜。
由以上分析我们可以得到结论:将所有的堆的石子数化为二进制后,如果所有数位上的1的个数都是偶数,那么先取者必败;如果有些位上的1的个数是奇数,先取者能够将所有数位上的1的个数都变为偶数的话,那么先取者必胜。
好,下面来分析我们的题目。
3,5,7,19,50化为二进制是:
000011
000101
000111
010011
110010
可见,只有最高位的1是奇数个,其他位上都是偶数个。
所以只需要将最高位的1取走即可必胜。
二进制的100000就是10进制的32,所以要将50个石子的那堆取32个,取掉就变成偶数个数目。于是先取者必胜。以后无论对方怎么取,始终保证每一位上的1的个数是偶数即可(一种简单的方法是,他在一堆中取几个,你在另一堆中也取几个就可以)。