七根火柴题

willyhan 2002-01-25 11:17:44
加精
题:七根火柴,甲乙两人每次抽取一到两根,最后抽取的人获胜。如果甲先抽,获胜的所有方案列印出来。
今天的一道考试题,几年没摸数据结构了,没做出来,好是沮丧!
...全文
408 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
willyhan 2002-01-28
  • 打赏
  • 举报
回复
感谢starfish,同时也敬佩无比!
我拿到这种题怎么也找不到思路,能否指教我,如何构思这类题?感激不尽!
cxjddd 2002-01-27
  • 打赏
  • 举报
回复
先下比赢。
starfish 2002-01-27
  • 打赏
  • 举报
回复
#include <iostream.h>

const int MAX_MATCH_COUNT = 100;
bool FirstWin[MAX_MATCH_COUNT + 1]; // FirstWin[i]=true 表示有i根火柴的时候先取者必胜,
// FirstWin[i]=false表示有i根火柴的时候先取者必败

int match_count, max_fetch; // match_count 火柴数目, max_fetch 每次最多可取的火柴的数目

int strategy[MAX_MATCH_COUNT]; // 用来记录取火柴的策略

int min(int a, int b) {
return (a < b ? a : b);
}

// 计算在哪些情况下先取者必胜或必败
void CalFirstWin()
{
FirstWin[0] = false;
for (int i = 1; i <= match_count; i++) {
FirstWin[i] = false;
for (int j = 1; j <= min(max_fetch, i); j++) {
if (FirstWin[i - j] == false) {
FirstWin[i] = true;
break;
}
}
}
}

// 打印必胜策略
void PrintStrategy(int n, bool A_Fetch, int step)
{
if (n == 0) {
for (int i = 0; i < step; i++) {
cout << strategy[i] << " ";
}
cout << endl;
return;
}

if (A_Fetch) { // 轮到A取
for (int i = 1; i <= min(max_fetch, n); i++) {
if (FirstWin[n - i] == false) {
strategy[step] = i;
PrintStrategy(n - i, false, step + 1);
return;
}
}
} else { // 轮到B取
for (int i = 1; i <= min(max_fetch, n); i++) {
// 对B的每一种取法都给出必胜策略
strategy[step] = i;
PrintStrategy(n - i, true, step + 1);
}
}
}

void main()
{
match_count = 7;
max_fetch = 2;

CalFirstWin();
if (FirstWin[match_count] == false) {
cout << "A can not win!" << endl;
} else {
PrintStrategy(match_count, true, 0);
}
}
journay 2002-01-27
  • 打赏
  • 举报
回复
倒推吧!
leopro 2002-01-26
  • 打赏
  • 举报
回复
只要使剩下的是三的倍数就行了
对于N根火柴情况
N mod 3 =0 则先抽的必输
否则先抽必胜!
congling 2002-01-25
  • 打赏
  • 举报
回复
如果要写出方案通过Next和next的组合就可以了,就是找0值.
A:7->6-->5->3-->2-->0
-->1-->0
-->4->3-->2-->0
-->1-->0




congling 2002-01-25
  • 打赏
  • 举报
回复
取火柴问题就是著名的Nim问题,当然你这个问题比较简单,不用Nim解决也可以

如果想了解,察看:
http://www.csdn.net/expert/topic/424/424009.shtm
Next(0)不存在,|0|=0
Next(1)={0},next(1)={0},|1|=1
Next(2)={0,1};next(2)={1,0} |2|=2
Next(3)={1,2};next(3)={1,2} |3|=0
Next(4)={2,3};next(4)={0,2} |4|=1
Next(5)={4,3};next(5)={1,0} |5|=2
Next(6)={5,4};next(6)={1,2} |6|=0
Next(7)={6,5};next(7)={0,2} |7|=1
因此7根火柴必胜。
可以证明,
|3k|=0
|3k+1|=1
|3k+2|=2





karma 2002-01-25
  • 打赏
  • 举报
回复
1fei(白天):
真的么?如果只有3根火柴呢?:-)
williexu 2002-01-25
  • 打赏
  • 举报
回复
提示思路:
从后往前算,最后剩下1/2根被甲抽到,依次往前加,乙抽、甲抽、乙抽、甲抽...,每次1/2根,如果加完后共是7根且为甲所加,则输出。
算法与货郎担类似。
willyhan 2002-01-25
  • 打赏
  • 举报
回复
最好请写出程序算法
1fei 2002-01-25
  • 打赏
  • 举报
回复
不管几根火柴都是先抽的胜
karma 2002-01-25
  • 打赏
  • 举报
回复
甲先抽1, 接下来,如果乙抽1,甲就抽2, 乙抽2,甲就抽1, .....


33,028

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧