我是靠谱客的博主 凶狠煎饼,最近开发中收集的这篇文章主要介绍猜生日,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

通过询问对方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

 


最后

以上就是凶狠煎饼为你收集整理的猜生日的全部内容,希望文章能够帮你解决猜生日所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部