java猜测生日游戏_猜生日游戏

通过一组特定的日期集合,本文揭示了一种巧妙的算法原理,能够仅凭用户对几个日期集合的回答来准确推断出用户的生日。该算法利用二进制表示和位运算,巧妙地将1到31号之间的任何一天的日期映射到了五个简单的Yes/No问题上。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在看《Java语言程序设计--基础篇》第3章有个有意思的例子,给出5组日期,只要回答你的日期是否在这5组日期即可猜出你的生日是哪天。这5组日期是:

1  3    5   7

9  11 13  15

17 19 21 23

25 27 29 31

2   3   6   7

10 11 14 15

18 19 22 23

26 27 30 31

4   5   6   7

12 13 14 15

20 21 22 23

28 29 30 31

8   9  10  11

12 13 14 15

24 25 26 27

28 29 30 31

16 17 18 19

20 21 22 23

24 25 26 27

28 29 30 31

如果你的生日是28号,那么你的回答应该是:0, 0, 1, 1, 1。这样程序就会猜出你的生日是28号。至于为什么是这样,书上也给出了对应的解释。

首先,这5组日期的第一个数分别是:1、2、4、8、16,它们分别对应的二进制是:1、10、100、1000、10000。而从1到31的十进制数,最多用5个二进制数就可以表示,这也就解释了为什么需要5组日期了。

其次,每组日期的数字也是有限制的,如果你把这些数字都换成二进制,就比较容易看出规律了,为了减少输入这里只列举第2组:

00010  00011  00110  00111

01010  01011  01110   01111

10010  10011  10110  10111

11010  11011  11110  11111

现在应该看出来它们的规律在哪儿了。没错,二进制的右边第2位都是1。其实,其他几组日期数字转换成二进制后的规律是:第1组二进制右边第1位都是1,第3组二进制右边第3位都是1,第4组二进制右边第4位都是1,第5组二进制数右边第5位都是1。按照这个规律,把1到31这些数字分成5组,并从小到大排列,就能得到上面的5组日期数字了。

我们再来看28号这天,数字28的二进制是:11100,而我们在前面的选择是:00111,正好两个二进制数的高位和低位反了。我们把11100反向后,就是00111了。而这也正是我们的选择。而28就是4,8,16的和。所以,我们推测是,如果你要选择的日期在某组日期中,回复的是1,就将该组日期中的第一个日期拿出来。然后,将所有回复为1的日期相加,最后得到你要选择的日期。

以下是Java代码:

import java.util.Scanner;

class GuessBirthday_3_3

{

public static void main(String[] args)

{

String set1 =

" 1 3 5 7\n" +

" 9 11 13 15\n" +

"17 19 21 23\n" +

"25 27 29 31\n";

String set2 =

" 2 3 6 7\n" +

"10 11 14 15\n" +

"18 19 22 23\n" +

"26 27 30 31\n";

String set3 =

" 4 5 6 7\n" +

"12 13 14 15\n" +

"20 21 22 23\n" +

"28 29 30 31";

String set4 =

"8 9 10 11\n" +

"12 13 14 15\n" +

"24 25 26 27\n" +

"28 29 30 31";

String set5 =

"16 17 18 19\n" +

"20 21 22 23\n" +

"24 25 26 27\n" +

"28 29 30 31";

int day = 0;

Scanner input = new Scanner(System.in);

System.out.print("Is your birthday in Set1?\n");

System.out.print(set1);

System.out.print("\nEnter 0 for No and 1 for Yes: ");

int answer = input.nextInt();

if (answer == 1)

{

day += 1;

}

System.out.print("\nIs your birthday in Set2?\n");

System.out.print(set2);

System.out.print("\nEnter 0 for No and 1 for Yes: ");

answer = input.nextInt();

if(answer == 1)

day += 2;

System.out.print("Is your birthday in Set3?\n");

System.out.print(set3);

System.out.print("\nEnter 0 for No and 1 for Yes: ");

answer = input.nextInt();

if (answer == 1)

{

day += 4;

}

System.out.print("\nIs your birthday in Set4?\n");

System.out.print(set4);

System.out.print("\nEnter 0 for No and 1 for Yes: ");

answer = input.nextInt();

if (answer == 1)

{

day += 8;

}

System.out.print("\nIs your birthday in Set5?\n");

System.out.print(set5);

System.out.print("\nEnter 0 for No and 1 for Yes: ");

answer = input.nextInt();

if (answer == 1)

{

day += 16;

}

System.out.print("\nYour birthday is " + day + "!");

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值