哪个游戏盒子里有JAVA_1254: 盒子游戏(Java)

哪个游戏盒子里有JAVA_1254: 盒子游戏(Java)参考博客 Description 有两个相同的盒子 其中一个装了 n 个球 另一个装了一个球 Alice 和 Bob 发明了一个游戏 规则如下 Alice 和 Bob 轮流操作 Alice 先操作 每次操作时 游戏者先看看哪个盒子里的球的数目比较少 然后清空这个盒子 盒子里的球直接扔掉 然后把另一个盒子里的球拿一些到这个盒子中 使得两个盒子都至少有一个球 如果一个游戏者无法进行操作 他 她 就输了 下图是一个典型的游

参考博客

Description

有两个相同的盒子,其中一个装了n个球,另一个装了一个球。Alice和Bob发明了一个游戏,规则如下:Alice和Bob轮流操作,Alice先操作。每次操作时,游戏者先看看哪个盒子里的球的数目比较少,然后清空这个盒子(盒子里的球直接扔掉),然后把另一个盒子里的球拿一些到这个盒子中,使得两个盒子都至少有一个球。如果一个游戏者无法进行操作,他(她)就输了。下图是一个典型的游戏:

6fd370288064354f892872452052fd45.png

面对两个各装一个球的盒子,Bob无法继续操作,因此Alice获胜。你的任务是找出谁会获胜。假定两人都很聪明,总是采取最优策略。

Input

输入最多包含300组测试数据。每组数据仅一行,包含一个整数n(2<=n<=10^9)。输入结束标志为n=0。

Output

对于每组数据,输出胜者的名字。

Sample Input

2

3

4

0

Sample Output

Alice

Bob

Alice

题目分析

n=2时,Alice(A)拿完球后,只能得到(1,1)这种情况,结果A赢。

3c2be2a46b049a21ec056c63a83209b8.png

n=3时,A先拿,只能得到(2,1),Bob(B)再拿,只能得到(1,1),结果B赢。

993d5ae1674612f7af22132167959981.png

n=4时,A一定会将球分成(3,1),B只能将球分成(2,1),A只能将球分成(1,1),结果A赢。

87a9665079ac30aa530920f1a6d7a8e5.pngn=5时,A一定会将球分成(3,2),B只能将球分成(2,1),A只能将球分成(1,1),结果A赢。

98f0a33517f4de026a7da665a2516857.pngn=6时,A一定会将球分成(3,3),B只能将球分成(2,1),A只能将球分成(1,1),结果A赢。

bd89bc9e56869628df4968e64cd34400.pngn=7时,无论A将球分成多少,B一定会将球分成(3,k)(k=1,2,3),A只能将球分成(2,1),B只能将球分成(1,1),结果B赢。(WPS流程图有限制。。。不规范的是我用图片编辑补充的。)

5aafbf2d024fea2e9350272df18a4442.png

结论1:当球的个数为(m,n)且满足1<=n<=m,m=2k-1(k=1,2,3,4,…)时,当前拿球的人一定会输。

由于Alice先拿球,我们可以这么理解,如果Alice不能将球分成结论1的情况,那么Bob一定会将球分成结论1的情况,从而导致自己输掉。

由于Alice先拿球,可以进一步将结论分成2个:

1、球的个数为结论1所示,Alice一定会输;

2、球的个数不为结论1所示,Alice都可以将球分成结论1所示,Alice一定会赢。

这里有必要说明一点,拿球结果只和球较多的那部分有关,较少的部分最终都会被扔掉,不必考虑。不明白就多看几遍上面的图并自行体会。

这里我们只需要证明第1条(即结论1)成立,第2条自然也就成立。下面就用数学归纳法来证明第1条是否成立:

解:

第一步,当k1=1时,盒子状态为(1,1),当前是Alice拿,因此Alice输;

第二步,当k2=k1+1时,盒子状态为(3,1),当前是Alice拿,因此Alice输;

第三步,令k=e时,球的状态为(2e-1,1)时,满足结论1,当前是Alice拿,因此Alice输;

当k=e+1时,球的状态为(2e+1-1,1),

Alice只能分成(m,n),且1<=n<=m,m+n=2e+1-1,

那么m的范围是[2e,2e+1-2],(与此对应的n的范围是[2e-1,1]),

因此可以看出m是大于k=e时的球个数2e-1的

也就是说,Alice是不可能将球的个数分成(2e-1,1)的,接下来Bob肯定将球分成(2e-1,1)从而让Alice拿,也就是让Alice输。

因此当k=e时,能够使k=e+1满足结论1,因此,结论1成立。结论得证。

代码

分析:当n=2k-1时,n的二进制是前面一串0,最后k个1,

因此n&1只有2种情况1和0,如果是1,将n右移1位;如果是0,退出右移循环。

此时判断n是否等于0,等于0说明n=2k-1,那么Alice输

不等于0,说明n最后一位的左边还有1,而最后一位是0,显然与开头说的最后k个1中的最后相矛盾,那么Alice赢。

// 这是参考博客的第一个的方法

// 提交用时:349ms

import java.util.Scanner;

public class Main {

private Scanner sc;

private int n;

public Main() {

sc = new Scanner(System.in);

n = sc.nextInt();

while(0 != n) {

while((n & 1) == 1) {

n >>= 1;

}

if(0 == n) {

System.out.println(“Bob”);

} else {

System.out.println(“Alice”);

}

n = sc.nextInt();

}

sc.close();

}

public static void main(String[] args) {

new Main();

}

}

分析:既然我们已经知道了Bob赢时的n值,那为何我们不将这些n值先算出来呢,再同输入的值相比较,这样对于数据较多(此题明确说了最多300组数据)时,肯定会缩短计算时间的。

// 这是参考博客的第二个的方法

// 提交用时:256ms

import java.util.Scanner;

public class Main {

private Scanner sc;

private int n, i;

private int[] bob;// 使得Bob赢的n值

public Main() {

sc = new Scanner(System.in);

bob = new int[32];

bob[0] = 1;

for(i = 1; i <= 31; i++) {

bob[i] = bob[i – 1] * 2 + 1;

}

n = sc.nextInt();

while(0 != n) {

for(i = 1; i <= 31; i++) {

if(n == bob[i]) {

System.out.println(“Bob”);

break;

} else if(n < bob[i]) {

System.out.println(“Alice”);

break;

}

}

n = sc.nextInt();

}

sc.close();

}

public static void main(String[] args) {

new Main();

}

}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/213117.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月18日 下午6:31
下一篇 2026年3月18日 下午6:31


相关推荐

  • 启动ucosii之四OSTaskCreate()[通俗易懂]

    启动ucosii之四OSTaskCreate()[通俗易懂]函数原型来自OS_TASK.C/***********************************************************************************************************                                           CREATEATASK**************

    2025年9月21日
    7
  • java中打印数组的方法_Java数组方法–如何在Java中打印数组

    java中打印数组的方法_Java数组方法–如何在Java中打印数组java中打印数组的方法Anarrayisadatastructureusedtostoredataofthesametype.Arraysstoretheirelementsincontiguousmemorylocations.数组是用于存储相同类型数据的数据结构。数组将其元素存储在连续的内存位置中。InJava,arraysareo…

    2022年6月3日
    36
  • 深入拆解 AI Coding Agent 的底层原理

    深入拆解 AI Coding Agent 的底层原理

    2026年3月15日
    2
  • Pycharm常用功能操作使用介绍

    Pycharm常用功能操作使用介绍学习笔记 Pycharm 是 Jetbrains 的一款产品 是 Python 的 IDE 之一 可以说是 Python 中最受欢迎的 IDE 常用功能一 创建 Python 项目 File gt NewProject 常用功能二 创建 python 文件右键一个文件目录 gt New gt PythonFile 常用功能三 定位当前目录所在的位置点击左侧

    2026年3月20日
    2
  • js 数组删除指定元素「建议收藏」

    js 数组删除指定元素「建议收藏」js数组删除指定元素,js数组并没有提供直接删除某一指定元素的方法,因此需要我们稍作处理思路:首先找到要删除的元素的位置,然后使用splice方法进行删除示例代码删除数组s中的‘dd’元素vars=[‘s’,’dd’,’re’]s.splice(s.indexOf(‘dd’),1)console.log(s)运行效果至此完…

    2022年8月11日
    8
  • rehash过程_contenthash

    rehash过程_contenthash步骤1)首先创建一个比现有哈希表更大的新哈希表(expand)2)然后将旧哈希表的所有元素都迁移到新哈希表去(rehash)dictAdd对字典添加元素的时候,_dictExpandIfNeeded会

    2022年8月3日
    6

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号