魔方吧·中文魔方俱乐部

 找回密码
 注册
搜索
热搜: 魔方
查看: 2232|回复: 3
打印 上一主题 下一主题

抓石子争单双博弈题 [复制链接]

Rank: 4

积分
1843
帖子
1468
精华
1
UID
79281
性别

四年元老

1#
发表于 2011-9-2 13:02:47 |显示全部楼层
写了个程序,确实是先手必胜,第一步可以在B里取3个。

使用道具 举报

Rank: 4

积分
1843
帖子
1468
精华
1
UID
79281
性别

四年元老

2#
发表于 2011-9-11 19:48:04 |显示全部楼层
这个问题规模很小,只有27^3=19683。用递归轻松搞定。 调用 s(27, 27, 27, 0) 返回的是 (27, 24, 27),表示第一步在B里取3个,以后根据对手的决策反复调用s就行了。
  1. #!/usr/bin/python3 -i


  2. def solver(a_max, b_max, c_max):
  3.     mem = {(0, 0, 0, 0): 'win',
  4.            (0, 0, 0, 1): 'lose'}

  5.     def adj(a, b, c):
  6.         return ([(i, b, c) for i in range(max(0, a - a_max), a)] +
  7.                 [(a, i, c) for i in range(max(0, b - b_max), b)] +
  8.                 [(a, b, i) for i in range(max(0, c - c_max), c)])

  9.     def rec(x):
  10.         if x not in mem:
  11.             p = ((sum(x) + 1) % 2,)
  12.             for y in adj(*x[:3]):
  13.                 if rec(y + p) == 'lose':
  14.                     mem[x] = y
  15.                     break
  16.             else:
  17.                 mem[x] = 'lose'
  18.         return mem[x]

  19.     return lambda a, b, c, p: rec((a, b, c, p))


  20. s = solver(3, 4, 5)
  21. print(s(27, 27, 27, 0))
复制代码

[ 本帖最后由 yq_118 于 2011-9-11 20:40 编辑 ]

使用道具 举报

Rank: 4

积分
1843
帖子
1468
精华
1
UID
79281
性别

四年元老

3#
发表于 2011-9-11 20:43:18 |显示全部楼层
这个是Python写的,用C的话要考虑太多与问题无关的东西。

使用道具 举报

Rank: 4

积分
1843
帖子
1468
精华
1
UID
79281
性别

四年元老

4#
发表于 2011-9-12 13:02:20 |显示全部楼层
稍加修改就能推广到一般的情况。
根据题目的要求调用solver,返回一个求解器。
调用求解器,第一个参数为一个向量,表示各堆的石子数,第二个参数表示奇偶性,0为偶,1为奇。
返回'lose'表示输了,否则返回一个向量表示决策。
  1. #!/usr/bin/python3 -i


  2. def solver(*m):
  3.     n = len(m)
  4.     mem = {((0,) * n, 0): 'win',
  5.            ((0,) * n, 1): 'lose'}

  6.     def adj(x):
  7.         for i in range(n):
  8.             y = list(x)
  9.             for y[i] in range(max(0, x[i] - m[i]), x[i]):
  10.                 yield tuple(y)

  11.     def rec(x, parity):
  12.         if (x, parity) not in mem:
  13.             q = (sum(x) + parity + 1) % 2
  14.             for y in adj(x):
  15.                 if rec(y, q) == 'lose':
  16.                     mem[(x, parity)] = y
  17.                     break
  18.             else:
  19.                 mem[(x, parity)] = 'lose'
  20.         return mem[(x, parity)]

  21.     return rec


  22. s = solver(3, 4, 5)
  23. print(s((27, 27, 27), 0))
复制代码

[ 本帖最后由 yq_118 于 2011-9-12 13:14 编辑 ]

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

Archiver|手机版|魔方吧·中文魔方俱乐部

GMT+8, 2024-5-19 07:52

Powered by Discuz! X2

© 2001-2011 Comsenz Inc.

回顶部