蓝桥杯 取球博弈

取球博弈

两个人玩取球的游戏。
一共有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;
	}
}

猜你喜欢

转载自blog.csdn.net/qq_34525938/article/details/79369134
今日推荐