蓝桥杯取球博弈

题目

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


此题因为双方都采用最聪明的取法,所以先观察最聪明的取法:在保证能取得奇数的情况下,尽量取大数,

如果实在保证不了,直接取可取的最大数,双方都这样取,直到结束,比较取得总球数的奇偶性;

比如可取球数为1 2 3

总球数为5时  用A、B代表双方:A->3,B->1,A->1结束,A输;

总球数为8时  A->3,B->3,A->2结束,平局

总球数为9时 A->3,B->3,A->2,B->1,结束,A赢

代码如下:

public static void main(String[] args) {
	Scanner sc = new Scanner(System.in);
	int[] a = new int[5];//堆数
	int[] b = new int[3];//能取球数
	for (int i = 0; i < 3; i++) {
		b[i] = sc.nextInt();
	}
	for (int i = 0; i < 5; i++) {
		a[i] = sc.nextInt();
	}
	for (int i = 0; i < 3; i++) {//给能取球数从大到小排列
		for (int j = 0; j < 3-i-1; j++) {
			if(b[j]>b[j+1]){
				int t = b[j];
				b[j] = b[j+1];
				b[j+1] = b[j];
			}
		}
	}
	for (int i = 0; i < 5; i++) {
		int x = 0, y = 0;//x第一个人的总球数,y第二个人的总球数
		while(a[i]!=0){
			if(b[0]>a[i]) break;//剩余的球比可取的最小数还小,则结束
			boolean x1 = false,y1 = false;//标记能不能取到奇数,true代表能
			for (int j = 2; j >= 0; j--) {
				if((x%2==0&&b[j]%2==0)||(x%2!=0&&b[j]%2!=0)){//取得球数和已有球数不能都为奇数,也不能都为偶数
					continue;
				}
				if(b[j]>a[i]) continue;
				x+=b[j];
				a[i]-=b[j];
				x1 = true;
				break;
			}
			if(!x1){//如果不能保证为奇数   取出一个最大的数
				for (int j = 2; j >= 0; j--) {
					if(b[j]>a[i]) continue;
					x+=b[j];
					a[i]-=b[j];
				}
			}
			for (int j = 2; j >= 0; j--) {//第二个人与第一个人取法上,原则相同
				if((y%2==0&&b[j]%2==0)||(y%2!=0&&b[j]%2!=0)){
					continue;
				}
				if(b[j]>a[i]) continue;
				y+=b[j];
				a[i]-=b[j];
				y1 = true;
				break;
			}
			if(!y1){
				for (int j = 2; j >= 0; j--) {
					if(b[j]>a[i]) continue;
					y+=b[j];
					a[i]-=b[j];
				}
			}
		}
		if(y==0){
			if(x==0)
				System.out.print(0+" ");
			else
				System.out.print("+"+" ");
		}else if(y%2==0&&x%2!=0){
			System.out.print("+"+" ");
		}else if(y%2!=0&&x%2==0){
			System.out.print("-"+" ");
		}else if(y%2==0&&x%2==0){
			System.out.print(0+" ");
		}else{
			System.out.print(0+" ");
		}
	}
}
欢迎指正~

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值