取球博弈
两个人玩取球的游戏。
一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目。
如果无法继续取球,则游戏结束。
此时,持有奇数个球的一方获胜。
第一个取球的人一定能赢吗?
试编程解决这个问题。
输入格式:
第一行3个正整数n1 n2 n3,空格分开,表示每次可取的数目 (0<n1,n2,n3<100)
第二行5个正整数x1 x2 ... x5,空格分开,表示5局的初始球数(0<xi<1000)
输出格式:
一行5个字符,空格分开。分别表示每局先取球的人能否获胜。
能获胜则输出+,
次之,如有办法逼平对手,输出0,
无论如何都会输,则输出-
例如,输入:
1 2 3
1 2 3 4 5
程序应该输出:
+ 0 + 0 -
再例如,输入:
1 4 5
10 11 12 13 15
程序应该输出:
0 - 0 + +
再例如,输入:
2 3 5
7 8 9 10 11
程序应该输出:
+ 0 0 0 0
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
两个人玩取球的游戏。
一共有N个球,每人轮流取球,每次可取集合{n1,n2,n3}中的任何一个数目。
如果无法继续取球,则游戏结束。
此时,持有奇数个球的一方获胜。
如果两人都是奇数,则为平局。
假设双方都采用最聪明的取法,第一个取球的人一定能赢吗?
试编程解决这个问题。
输入格式:
第一行3个正整数n1 n2 n3,空格分开,表示每次可取的数目 (0<n1,n2,n3<100)
第二行5个正整数x1 x2 ... x5,空格分开,表示5局的初始球数(0<xi<1000)
输出格式:
一行5个字符,空格分开。分别表示每局先取球的人能否获胜。
能获胜则输出+,
次之,如有办法逼平对手,输出0,
无论如何都会输,则输出-
例如,输入:
1 2 3
1 2 3 4 5
程序应该输出:
+ 0 + 0 -
再例如,输入:
1 4 5
10 11 12 13 15
程序应该输出:
0 - 0 + +
再例如,输入:
2 3 5
7 8 9 10 11
程序应该输出:
+ 0 0 0 0
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 3000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
注意:不要使用package语句。不要使用jdk1.7及以上版本的特性。
注意:主类的名字必须是:Main,否则按无效代码处理。
这道题我是没有查百度,自己先写的,所以代码有点冗长
主要的思路就是 先用 +1 0 -1 分别代表必胜,逼平,必败
然后四维数组 a[i][j][k][l] 的解释
i表示轮到谁下,i=0表示轮到我,i=1表示轮到对手
j表示我的持球奇偶,j=1,表示我持奇数个球;j=0,表示我持偶数个球
k表示对手持球奇偶,k=1,表示对手持奇数,k=0表示对手持偶数
l表示剩球数,还剩下多少个球可以拿
这样 a[i][j][k][l]就可以唯一的表示一种局面!
然后关于递推,如果i=0,也就是轮到我下的话,是max函数,就是能1我会走到1,没有1再看看有没有办法平,全是-1就必败了,所以是max函数
如果i=1,也就是对手下,是min函数,如果能让我-1他选这种局面,如果没有能让我-1的,他会找逼平的,不管怎么走他都只能让我1,那么就是1
所以就是一个a[i][j][k][l]表示任何一种局面,然后i=0是max决策函数;i=1是min决策函数
代码如下(代码有点冗长,建议参考网上其他代码):
import java.util.Arrays;
import java.util.Scanner;
class Main{
static int []q=new int[3]; //取数数组
static int [][][][]a=new int[2][2][2][1000]; //df数组
static int []g=new int[3]; //决策数组
public static void main(String[] args) {
Scanner s=new Scanner(System.in);
for(int i=0;i<3;i++)
q[i]=s.nextInt();
Arrays.sort(q);
s.nextLine();
for(int i=0;i<2;i++)
for(int j=0;j<2;j++)
for(int k=0;k<2;k++)
for(int l=0;l<1000;l++) //初始化
{
if(l<q[0])
{
if((j==0&&k==0)||(j==1&&k==1))
a[i][j][k][l]=0;
if((j==0&&k==1))
a[i][j][k][l]=-1;
if((j==1&&k==0))
a[i][j][k][l]=1;
}else
{
a[i][j][k][l]=2;
}
}
String []input=s.nextLine().split(" ");
for(int i=0;i<input.length;i++)
{
int temp=(f(0,0,0,Integer.parseInt(input[i])));
if(temp==0)
System.out.print("0 ");
if(temp==1)
System.out.print("+ ");
if(temp==-1)
System.out.print("- ");
}
}
private static int f(int i, int j, int k, int l) {
if(a[i][j][k][l]!=2)
return a[i][j][k][l];
g[0]=g[1]=g[2]=2;
for(int m=0;m<3;m++)
if(l>=q[m])
{
if(i==0)
{
g[m]=f(1-i,(j+q[m])%2, k, l-q[m]);
}else{
g[m]=f(1-i, j,(k+q[m])%2, l-q[m]);
}
}
return a[i][j][k][l]=juice(i,g);
}
private static int juice(int k,int[] g) {
int max=-1,min=1;
for(int i=0;i<g.length;i++)
{
if(g[i]!=2)
{
max=max>g[i]?max:g[i];
min=min<g[i]?min:g[i];
}
}
g[0]=g[1]=g[2]=2;
return (k==0)?max:min;
}
}