在某群看到的题目,用代码实现,题目如下:山乡希望小学收到一箱捐赠图书,邮件上署名是“兴华中学高二班”,山乡希望小学校 长送来了感谢信,可是兴华中学高二年级有四个班,校长找来了四个班的班长,问他们是哪 个班做的这件好事。一班的班长说:“是四班做的。”二班的班长说:“是三班做的好事。”三 班的班长说:“不是我们班。” 四班的班长说:“三班的班长说的不对。” 
四个班的班长都说不是自己班做的,这就难坏了校长,后来得知四个班的班长中有两个 说得是真话,有两个没有说真话,请你利用计算机的逻辑判断编一个程序,找出究竟是哪个班做了这件好事。不能手算后直接打印结果。大家都来写写吧..
我自己的代码如下:procedure TForm1.Button2Click(Sender: TObject);
var Count:integer;    //符合条件的数量
    i:integer;        //班的数量
begin
  
  for i:=1 to 4 do
  begin
    Count:=0;
    if i=4 then Count:=Count+1;      //1班说是4班
    if i=3 then Count:=Count+1;      //2班说是3班
    if i<>3 then Count:=Count+1;     //3班说不是自己
    if i=3 then Count:=Count+1;      //4班说3班说的不对
    if Count=2 then showmessage('是'+IntToStr(i)+'班做的');   //题目为有两个说真话。
  end;
end;

解决方案 »

  1.   

    楼主的程序不能判定是哪一个班:
    因为当i=1 (或i=2)时,Count=1,不符合条件。
    但当 i=3时,Count=2,是否就是3班?
    i=4时,也是Count=2,是否就是4班?
    做好事的只有一个班,那么到底是3班还是4班呢?
      

  2.   

    1(班):0(计数),2:0,3:0,4:0原始操作(全对):
    初始:x := 0000b;
    是四班做的: x := 1000b (x = 1000)
    是三班做的好事: x := x and 0100b (x = 0000)
    不是我们班(三班): x := x and 1011b (x = 0000)
    三班的班长说的不对: x := x and 0100b (x = 0000)
    结果:1100(即三班和四班做,结果无效)有两个说假话,两个说真话,因此可以通过排列组合来完成,则四个班的组合有:
    1100,1010,1001,0110,0101,0011
    x1_1 = 1000b, x1_0 = 0111b
    x2_1 = 0100b, x2_0 = 1011b
    x3_1 = 1011b, x3_0 = 0100b
    x4_1 = 0100b, x4_0 = 1011b1100: 1000b and 0100b and 0100b and 1011b = 0000b (fail)
    1010: 1000b and 1011b and 1011b and 1011b = 1000b (success)
    1001: 1000b and 1011b and 0100b and 0100b = 0000b (fail)
    0110: 0111b and 0100b and 1011b and 1011b = 0000b (fail)
    0101: 0111b and 0100b and 0100b and 0100b = 0100b (success)
    0011: 0111b and 1011b and 1011b and 0100b = 0000b (fail)结果有两个:
    1. 一班对,二班错,三班对,四班错
    2. 一班错,二班对,三班错,四班对
      

  3.   

    更正一下:
    原始操作(全对):
    初始:x := 0000b;
    是四班做的: x := 1000b (x = 1000)
    是三班做的好事: x := x and 0100b (x = 0000)
    不是我们班(三班): x := x and 1011b (x = 0000)
    三班的班长说的不对: x := x and 0100b (x = 0000)
    结果:0000(即三班和四班做,结果无效)