A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 qq892384796 于 2015-11-23 12:39 编辑

       前言:软妹子一枚,苦于还没有技术分不能入学,开始漫长的泡吧生活...不造怎样的贴才能赚技术分,也不希望自己发水帖(男票不让发水贴),所以以后发的都是自己学到的新东西或者觉得比较有意思的贴贴。      
       今天就介绍几道遇到的比较有意思的编程题,分享给大家:
       1.哪个大夫哪天值班
      医院有A、B、C、D、E、F、G七位大夫,在一个星期内(星期一至星期天)每人要轮流值班一天。现在已知:
      A大夫比C大夫晚一天值班;
      D大夫比E大夫晚二天值班;
      B大夫比G大夫早三天值班;
      F大夫的值班日在B和C大夫的中间,且是星期四;
      请确定每天究竟是哪位大夫值班?

      解题思路:
             对于这种多对多搭配问题,一眼看过去就想到穷举暴力破解即可(80%问题穷举都能解决),解题思路已经有了,剩下的就是分析条件,优化穷举范围。
  条件1:医院有A、B、C、D、E、F、G七位大夫,在一个星期内(星期一至星期天)每人要轮流值班一天;
           7个人,每人值班1天,设int变量a,b,c,d,e,f,g分别代表7个人,则他们的值为1~7为星期几,得:
           a!=b&&a!=c&&a!=d&&a!=e&&a!=f&&a!=g ;
           b!=c&&b!=d&&b!=e&&b!=f&&b!=g;
           c!=d&&c!=e&&c!=f&&c!=g
            ...
  条件2:  A大夫比C大夫晚一天值班; 得:a==c+1
  条件3:  D大夫比E大夫晚二天值班; 得:d==e+2
  条件4:  B大夫比G大夫早三天值班; 得:b==g-3
  条件5:  F大夫的值班日在B和C大夫的中间,且是星期四;
          f在b和c之间可得:(b+c)%f==0   eg:  (5+3)% 4 == 0
          且直接告诉我们: f=4

      通过分析以上条件,代码就好写多了:
  1. public static void main(String args[]) {

  2.                 int a, b, c, d, e, f = 4, g; //已知f医生星期四上班
  3.                 //穷举其他医生
  4.                 for (a = 1;  a <= 7; a++) {
  5.                 for (b = 1;  b <= 7; b++) {
  6.                 for (c = 1;  c <= 7; c++) {
  7.                 for (d = 1;  d <= 7; d++) {
  8.                 for (e = 1;  e <= 7; e++) {
  9.                 for (g = 1;  g <= 7; g++) {
  10.                         //每人一天,不能重复
  11.                         if (a != b && a != c && a != d && a != e
  12.                                         && a != f && a != g && b != c && b != d
  13.                                         && b != e && b != f && b != g && c != d
  14.                                         && c != e && c != f && c != g && d != e
  15.                                         && d != f && d != g && e != f && e != g
  16.                                         && f != g)
  17.                                
  18.                                 if ((a == c + 1) && (d == e + 2) //加入比较条件
  19.                                                 && (b == g - 3)
  20.                                                 && ((b + c) % f == 0)
  21.                                                 && (b + c > 4)) {
  22.                                        
  23.                                         //满足所有条件,打印结果
  24.                                         System.out.println("a\tb\tc\td\te\tf\tg");
  25.                                         System.out.println(a + "\t" + b + "\t"
  26.                                                         + c + "\t" + d + "\t" + e
  27.                                                         + "\t" + f + "\t" + g);
  28.                                         System.out.println("---------------------------------------------------");
  29.                                 }
  30.                 }}}}}}
  31.         }
复制代码
运行结果:
  

  如果以上这道有趣的小问题小伙伴们看懂了,那么下面咱们再来一道吧!

  2.谁是窃贼
   公安人员审问四名窃贼嫌疑犯。
   已知,这四人当中仅有一名是窃贼,还知道这四人中每人要么是诚实的,要么总是说谎的。在回答公安人员的问题中:
   甲说:“乙没有偷,是丁偷的。”
   乙说:“我没有偷,是丙偷的。”
   丙说:“甲没有偷,是乙偷的。”
   丁说:“我没有偷。”
   请根据这四人的答话判断谁是盗窃者。
   
   是不是有些小小的头晕,又是说谎又是偷东西的什么跟什么啊,哈哈,不要急管他谁偷谁抢的,让我们的代码去告诉我们吧!

   解题思路:
   既然偷与没偷、说谎与没说谎傻傻分不清楚,那么就不要混在一起来求解喽,测谎我们用一组变量j1,y1,b1,d1分别表示甲乙丙丁是否说谎(值0表示说谎,1表示诚实),偷盗再使用一组变量j2,y2,b2,d2表示甲乙丙丁是否偷盗(值0表示好人,1表示盗贼),同上面一样通过穷举法,找到可恶的盗贼。
    条件1:这四人当中仅有一名是窃贼,还知道这四人中每人要么是诚实的,要么总是说谎的
       只有一名盗贼得:2+y2+b2+d2=1
       以及:四人说的话要么全假话,要么全真话,不会半真半假(很重要哦)
   条件2: 甲说:“乙没有偷,是丁偷的。”
      真话得:j1==1&&(y2==0&&d2==1)
      假话得:j1==0&&(y2==1&&d2==0)
  条件3:乙说:“我没有偷,是丙偷的。”
      真话得:y1==1&&(y2==0&&b2==1)
      假话得:y1==0&&(y2==1&&b2==0)
  条件4:丙说:甲没有偷,是乙偷的。”
     真话得:b1==1&&(j2==0&&y2==1)
     假话得:b1==0&&(j2==1&&y2==0)
  条件5:丁说:“我没有偷。”
    真话得:d1==1&&(d2==0)
    假话得:d1==0&&(d2==1)
好了,准备就绪,开始抓贼吧。
  1. public static void main(String args[])
  2.         {
  3.                 int j1, y1, b1, d1,j2, y2, b2, d2;
  4.                 for(j1=0;j1<=1;j1++)
  5.                 for(y1=0;y1<=1;y1++)
  6.                 for(b1=0;b1<=1;b1++)
  7.                 for(d1=0;d1<=1;d1++)
  8.                     for(j2=0;j2<=1;j2++)
  9.                     for(y2=0;y2<=1;y2++)
  10.                     for(b2=0;b2<=1;b2++)
  11.                     for(d2=0;d2<=1;d2++)
  12.                         if(j2+y2+b2+d2==1)
  13.                         if(((j1==1&&(y2==0&&d2==1))||(j1==0&&(y2==1&&d2==0)))&&((y1==1&&(y2==0&&b2==1))||(y1==0&&(y2==1&&b2==0)))&&((b1==1&&(j2==0&&y2==1))||(b1==0&&(j2==1&&y2==0)))&&((d1==1&&(d2==0))||(d1==0&&(d2==1))))
  14.                 {
  15.                         System.out.println("值为0的说谎:甲="+j1+",乙="+y1+",丙="+b1+",丁="+d1);       
  16.                         System.out.printf("值为1的盗贼:甲="+j2+",乙="+y2+",丙="+b2+",丁="+d2);
  17.                 }
  18.         }
复制代码
   抓到贼啦:

     原来这个盗贼还有同伙啊,太可恶了,甲一直在帮乙开拓,警察叔叔,快把他们两个抓起来!

2 个回复

倒序浏览
啦啦啦~
回复 使用道具 举报
赞一个
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马