概述
通过询问对方5个问题,每个问题均是提问其生日在不在给出的集合中,如果是则输入1,不是输入0,那么在5个回合后,程序将给出这个人生日为几号。
参考《Foundations of Programming in Java》,下面是代码,代码有注释,就不多分析了,如果对代码有疑问的请在评论区留言,算法原理解析在最后,如果对这个算法还有更好的理解也请在评论区留言。
import java.util.Scanner;
public class GuessBirthday {
public static void main(String[] args) {
String set1 =
" 1 3 5 7n" +
" 9 11 13 15n" +
"17 19 21 23n" +
"25 27 29 31";
String set2 =
" 2 3 6 7n" +
"10 11 14 15n" +
"18 19 22 23n" +
"26 27 30 31";
String set3 =
" 4 5 6 7n" +
"12 13 14 15n" +
"20 21 22 23n" +
"28 29 30 31";
String set4 =
" 8 9 10 11n" +
"12 13 14 15n" +
"24 25 26 27n" +
"28 29 30 31";
String set5 =
"16 17 18 19n" +
"20 21 22 23n" +
"24 25 26 27n" +
"28 29 30 31";
int day = 0;
// Create a Scanner
Scanner input = new Scanner(System.in);
// Prompt the user to answer questions
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;
// Prompt the user to answer questions
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;
// Prompt the user to answer questions
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;
// Prompt the user to answer questions
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;
// Prompt the user to answer questions
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.println("nYour birthday is " + day + "!");
}
}
解析:假设小红同学的生日为某月19号,(下图是输入和结果解析)因为第一步中有19号所以需要输入1,第二步中也有19号同样输入1,第三步和第四步没有19号,输入0,第五步有19号需要输入1,所以输入1的是1,2,5步,用左上角数字加起来刚好是小红生日的号数19号。
下图为程序运行过程的输入和输出:
算法的原理:
生日只能是[1,28](平年二月),[1,29](瑞年二月),[1,30](小月),[1,31](大月)号中的某一天,不会超过31天,所以用[1,31]天完全能够表示小红的生日的号数,31的二进制位11111=00001+00010+00100+01000+10000,也就是:
00001--------------1
00010--------------2
00100--------------4
01000--------------8
+ 10000--------------16
——————————————————————
11111--------------31
然而我们知道,二进制只能由0或者1组成,所以一个数字[1,31]的各个位数只能是0或者1,所以由上面的数组合可以组合相加,可以得到任意一个数字。这样的话,我们任意取一个数字,其二进制表示为:ABCDE(注:对应A表示二进制由左往右第一位,B第二位,C第三位,D第四位,E第五位。例:10110,则A=1,B=0,C=1,D=1,E=0).
则ABCDE可以由如下算式得到:
0000E
000D0
00C00
0B000
+ A0000
———————————————————
ABCDE
显然这个ABCDE是任意的,并且A,B,C,D,E要么为0要么为1。这样我们可以将对应的生日放在5个集合的某个集合中,
规则是:
如果这个数的E=1(不限定其他位数字),那么就应该放在集合set1中。
如果这个数的D=1(不限定其他位数字),那么就应该放在集合set2中。
如果这个数的C=1(不限定其他位数字),那么就应该放在集合set3中。
如果这个数的B=1(不限定其他位数字),那么就应该放在集合set4中。
如果这个数的A=1(不限定其他位数字),那么就应该放在集合set5中。
注:可能一个生日会放在多个集合中。
当将这些生日放置在不同的集合中后,通过指定某个生日存在于5个集合中的哪些集合。我们便可以轻易的得到这个生日号数。
例:小红的生日19号(本篇算法只讨论号数),其二进制为10011,那么我们会将它放置到set1,set2,set5中。
这样当你指定说某个数在集合set1,set2,set5,那么我们便知道,你说的某数必然是E=1,D=1,C=0,B=0,A=1
很容易的我们便可以猜出你说的某数为1+2+0+0+16=19。
最后
以上就是凶狠煎饼为你收集整理的猜生日的全部内容,希望文章能够帮你解决猜生日所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复