这个问题是我在监考时闲来无事,一位同事突然跟我说了这么一个游戏,我起初以为是简单的为佐夫博弈,没想到一丁点的改动,竟然会是大相径庭!
题意:
现在进行以下游戏,规则如下
有3堆纸团,分别为3,5,7,规定两人轮流取纸团,每次最多只能从一堆中取1-n个,规定谁取到最后一个为输。
现在问假设我第一个取,有没有办法一定取胜
分析:
典型的为佐夫博弈,可是为佐夫博弈是取到最后一个为赢,因此结果会大相径庭。
1.寻找第一个必败局势 001
2.从这一点出发找到所有的必败局势
3.找到所有的必胜局势
4.找到必胜局势转化为必败局势的方法
以下解决这个问题的通解(可以是任意的a,b,c三个值)
import java.util.ArrayList;
import java.util.Arrays;
public class Main {
static ArrayList<String>al = new ArrayList<String>();
static int is(String s){
char[]cs = s.toCharArray();
char[]csa;
for (int i = 0; i < cs.length; i++)
{
char tmp = cs[i];
for (char j = cs[i]; j>='0'; j--) {
cs[i]=j;
csa=Arrays.copyOf(cs, cs.length);
Arrays.sort(csa);
String tsString = String.valueOf(csa);
if(tsString.equals("000"))return 4;
int in=al.indexOf(tsString);
if(in!=-1)return in;
}
cs[i]=tmp;
}
return -1;
}
public static void main(String[] args) {
al.add("001");
for (int i = 0; i <= 3; i++) {
for (int j = 0; j <=5; j++) {
for (int j2 = 0; j2 <=7; j2++) {
if(is(i+""+j+""+j2)<0){
String string = i+""+j+""+j2;
char [] cs = string.toCharArray();
Arrays.sort(cs);
al.add(String.valueOf(cs));
}
}
}
}
System.out.println("必败局势!");
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
System.out.println("必胜局势!");
for (int i = 0; i <= 3; i++) {
for (int j = i; j <=5; j++) {
for (int k = j; k <=7; k++) {
String string = i+""+j+""+k;
char [] cs = string.toCharArray();
Arrays.sort(cs);
int in=al.indexOf(String.valueOf(cs));
if(String.valueOf(cs).equals("000"))continue;
if(in<0){
int ia = is(String.valueOf(cs));
System.out.println("必胜:"+String.valueOf(cs)+" -> 必败:"+al.get(ia));
}
}
}
}
}
}
运行结果:
必败局势!
001
022
033
044
055
111
123
145
246
257
347
356
必胜局势!
必胜:002 -> 必败:001
必胜:003 -> 必败:001
必胜:004 -> 必败:001
必胜:005 -> 必败:001
必胜:006 -> 必败:001
必胜:007 -> 必败:001
必胜:011 -> 必败:001
必胜:012 -> 必败:001
必胜:013 -> 必败:001
必胜:014 -> 必败:001
必胜:015 -> 必败:001
必胜:016 -> 必败:001
必胜:017 -> 必败:001
必胜:023 -> 必败:022
必胜:024 -> 必败:022
必胜:025 -> 必败:022
必胜:026 -> 必败:022
必胜:027 -> 必败:022
必胜:034 -> 必败:033
必胜:035 -> 必败:033
必胜:036 -> 必败:033
必胜:037 -> 必败:033
必胜:045 -> 必败:044
必胜:046 -> 必败:044
必胜:047 -> 必败:044
必胜:056 -> 必败:055
必胜:057 -> 必败:055
必胜:112 -> 必败:111
必胜:113 -> 必败:111
必胜:114 -> 必败:111
必胜:115 -> 必败:111
必胜:116 -> 必败:111
必胜:117 -> 必败:111
必胜:122 -> 必败:022
必胜:124 -> 必败:123
必胜:125 -> 必败:123
必胜:126 -> 必败:123
必胜:127 -> 必败:123
必胜:133 -> 必败:033
必胜:134 -> 必败:123
必胜:135 -> 必败:123
必胜:136 -> 必败:123
必胜:137 -> 必败:123
必胜:144 -> 必败:044
必胜:146 -> 必败:145
必胜:147 -> 必败:145
必胜:155 -> 必败:055
必胜:156 -> 必败:145
必胜:157 -> 必败:145
必胜:222 -> 必败:022
必胜:223 -> 必败:123
必胜:224 -> 必败:022
必胜:225 -> 必败:022
必胜:226 -> 必败:022
必胜:227 -> 必败:022
必胜:233 -> 必败:033
必胜:234 -> 必败:123
必胜:235 -> 必败:123
必胜:236 -> 必败:123
必胜:237 -> 必败:123
必胜:244 -> 必败:044
必胜:245 -> 必败:145
必胜:247 -> 必败:246
必胜:255 -> 必败:055
必胜:256 -> 必败:246
必胜:333 -> 必败:033
必胜:334 -> 必败:033
必胜:335 -> 必败:033
必胜:336 -> 必败:033
必胜:337 -> 必败:033
必胜:344 -> 必败:044
必胜:345 -> 必败:145
必胜:346 -> 必败:246
必胜:355 -> 必败:055
必胜:357 -> 必败:257
由此看出:
3,5,7是必胜局势,即先取者肯定有办法取胜