两个有趣的逻辑推理题用编程来解答


1.   日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。以下为4个嫌疑犯的供词。
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。

#include
int main()
{
  int i,sum=0,flag=0;
  char killer;
  for(i=1;i<=4;i++)
  {
	  killer = 64+i;
      sum = (killer !='A')+(killer =='C')+(killer =='D') +(killer!='D');
      if(sum == 3)
	  {
		  flag=1;
		  printf("%c is the killer.\n",killer);
		  break;
	  }
  }
  if(flag ==0)
  printf("Can not find\n");
  return 0;
  }

       这个题母 killer = 64,这一步很关键,这相当于把ABCD的条件和ASCII的数值对应起来了,条件有说道三个人说了真话,所以用到了sum,说的真话即为条件为真数值为1,三个人说了真话则sum为3,定义flag是为了后边判断没有找到的另一种可能,找到的话用break直接跳出for循环。最后编程结果为:



2.  5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果
A选手说:B第一,我第三。
B选手说:我第二,E第四。
C选手说:我第一,D第二。
D选手说:C最后,我第三。
E选手说:我第四,A第一。
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

#include 
#include 
int main()
{
    int p[5];
    int t[6];
    int i,c,f;
    for(p[0]=1;p[0]<=5;p[0]++)
	{
        for(p[1]=1;p[1]<=5;p[1]++)
		{
            for(p[2]=1;p[2]<=5;p[2]++)
			{
                for(p[3]=1;p[3]<=5;p[3]++)
				{
                    for(p[4]=1;p[4]<=5;p[4]++)
					{
                        if((p[1]==1)+(p[0]==3)==1&&(p[1]==2)+(p[4]==4)==1&&(p[2]==1)+(p[3]==2)==1&&(p[4]==4)+(p[0]==1)==1)
						{
							memset(t,0,sizeof(t));
                                                        for(i=0;i<5;i++)
							{
								t[p[i]]++;   //记录每个名次有多少人
							}
                                                       for(i=5;i>=1;i--)
							{
								if(t[i]!=0)   //记录最后一名的名次i
								break;
							}
                                                      if((p[3]==3)+(p[2]==i)!=1)
								continue;     //D say

							//检查名次是否正确
                                                              if(t[1]==0)
								continue;
                                                               c=0;f=0;
                                                     for(i=1;i<=5;i++)
						    {
                                                             c+=t[i];
                                                              if(c==5)
							      break;
                                                              if(t[i]>=1)
							     {
                                                              if(t[i+1]==0)
								  {
                                                                      f=1;
								      break;
                                                                 }
                                                              }
                                                    }
                                                   if(f==1)
					           continue;
                            printf("A:%d\tB:%d\tC:%d\tD:%d\tE:%d\n",p[0],p[1],p[2],p[3],p[4]);
                        }
                    }
                }
            }
        }
    }
    return 0;
}


这个程序是网上参考,存在争议,不过大致思路都是先利用循环把所有可能都罗列出啦,然后根据所给条件进行判断。首先定义数组,利用五重for循环给出五人排名的所有可能,接下来条件判断,主要问题就在于五个人说的话都对了一半,同样是用if条件判断五人的所说对一半这个条件,用t[ p[ i ] ]++;确定每个名次有几人。因为题目并没有给出说明名次一样的时候排名的确定,所以在有相等排名不空缺的这种情况下,最后所得结果是:


        对于这种题目对我们初学者来说最大的问题就是思路,是缺少把实际的问题转换成为逻辑语言的这种思路,多看多写能帮助我们慢慢的开拓这种思维。




你可能感兴趣的:(C/C++)