猜生日游戏

在看《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 + "!");

	}
}



  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值