本帖最后由 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
通过分析以上条件,代码就好写多了: - public static void main(String args[]) {
- int a, b, c, d, e, f = 4, g; //已知f医生星期四上班
- //穷举其他医生
- for (a = 1; a <= 7; a++) {
- for (b = 1; b <= 7; b++) {
- for (c = 1; c <= 7; c++) {
- for (d = 1; d <= 7; d++) {
- for (e = 1; e <= 7; e++) {
- for (g = 1; g <= 7; g++) {
- //每人一天,不能重复
- if (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 && d != e
- && d != f && d != g && e != f && e != g
- && f != g)
-
- if ((a == c + 1) && (d == e + 2) //加入比较条件
- && (b == g - 3)
- && ((b + c) % f == 0)
- && (b + c > 4)) {
-
- //满足所有条件,打印结果
- System.out.println("a\tb\tc\td\te\tf\tg");
- System.out.println(a + "\t" + b + "\t"
- + c + "\t" + d + "\t" + e
- + "\t" + f + "\t" + g);
- System.out.println("---------------------------------------------------");
- }
- }}}}}}
- }
复制代码 运行结果:
如果以上这道有趣的小问题小伙伴们看懂了,那么下面咱们再来一道吧!
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) 好了,准备就绪,开始抓贼吧。 - public static void main(String args[])
- {
- int j1, y1, b1, d1,j2, y2, b2, d2;
- for(j1=0;j1<=1;j1++)
- for(y1=0;y1<=1;y1++)
- for(b1=0;b1<=1;b1++)
- for(d1=0;d1<=1;d1++)
- for(j2=0;j2<=1;j2++)
- for(y2=0;y2<=1;y2++)
- for(b2=0;b2<=1;b2++)
- for(d2=0;d2<=1;d2++)
- if(j2+y2+b2+d2==1)
- 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))))
- {
- System.out.println("值为0的说谎:甲="+j1+",乙="+y1+",丙="+b1+",丁="+d1);
- System.out.printf("值为1的盗贼:甲="+j2+",乙="+y2+",丙="+b2+",丁="+d2);
- }
- }
复制代码 抓到贼啦:
原来这个盗贼还有同伙啊,太可恶了,甲一直在帮乙开拓,警察叔叔,快把他们两个抓起来! |