4个人有3个人说真话,找说假话的人。求解释变量n的含义

时间:2022-04-11 21:57:42
张山说:不是我。李四说:是王五。王五说:是赵六。赵六说:不是我。
代码如下:
#include <iostream>
int main()
{
using namespace std;
char *man[]={"张三","李四","王五","赵六"};
for(int n=0;n<4;n++)                                                     //n既为循环控制变量,也表示第N个人
{if ((n!=0)+(n==2)+(n==3)+(n!=3)==3)                     //如果4句话有3句为真,则是该人说假话
cout<<"说假话的人是:"<<man[n]<<endl;}
return 0;
}

求高手解释下变量n的含义。始终想不通。n即是循环次数,又代表说假话的人。逻辑在哪里????

12 个解决方案

#1


这个题目人脑推理的话也很简单吧,只有一个人说假话,那么立马可以推断在王五和赵六之间,因为他们两个的说法是矛盾的,那么其他两个说的就是对的,所以通过李四就知道是王五说假话

#2


我知道现实中人脑推理很简单,但是我想说的是程序里的那个代码逻辑,我想不通,变量N为什么可以表示循环的同时(在if条件满足的情况下)还正好表示说谎人的指针位置。

#3


引用 1 楼 starytx 的回复:
这个题目人脑推理的话也很简单吧,只有一个人说假话,那么立马可以推断在王五和赵六之间,因为他们两个的说法是矛盾的,那么其他两个说的就是对的,所以通过李四就知道是王五说假话

if里面的那个条件我看不懂,现实中人脑推理简单我知道,我想知道的是if里面那个条件代码的逻辑。

#4


穷举法。n 代表依次试探的说假话的人的下标。注释已经很清楚了,if里面的四个括号分别是4个人各自说真话的判断条件,如果刚好满足3个true的条件,则 n 为所求打印结果。
比如张三的下标是0,那么张三说真话的判断条件就是 n != 0
李四说真话的判断条件是 n == 2 因为 2 是王五的下标。

#5


顶楼上的,他分析的很清楚了。

#6


个人觉得这个代码逻辑没道理,楼主不用去纠结。从代码的if来看已经知道2在说假话了,干嘛还要去判断。而且这里也不存在判断,都已经定死了2是说假话的人。

#7


假设n代表的是说假话的人
一共四个人char *man[]={"张三","李四","王五","赵六"};
for从第一个人开始假设他说的是假话,
如第一次循环,假设张三说的假话。张三说:“不是我”,张三的条件是(n!=0)== false,那么其他三人就应该是真,
但是李四说:“是王五”,条件是(n=2)显然不成立,因此第一次循环条件不成立。
依次类推,进入第二次循环判断,显然也不成立。
进入第三次循环判断,发现王五说的是假话。

#8


个人觉得这个代码逻辑没道理,楼主不用去纠结。从代码的if来看已经知道2在说假话了,干嘛还要去判断。而且这里也不存在判断,都已经定死了2是说假话的人。

#9


引用 楼主 xiji4482 的回复:
张山说:不是我。李四说:是王五。王五说:是赵六。赵六说:不是我。
代码如下:
#include <iostream>
int main()
{
using namespace std;
char *man[]={"张三","李四","王五","赵六"};
for(int n=0;n<4;n++)                                                     //n既为循环控制变量,也表示第N个人
{if ((n!=0)+(n==2)+(n==3)+(n!=3)==3)                     //如果4句话有3句为真,则是该人说假话
cout<<"说假话的人是:"<<man[n]<<endl;}
return 0;
}

求高手解释下变量n的含义。始终想不通。n即是循环次数,又代表说假话的人。逻辑在哪里????


因为man[0]=张三,。。。man[3]=赵六,所以n可以表示说假话的人。
因为是4个人里循环一次,所以n是循环次数

#10


这个问题蛮有意思的,哈哈!
我的理解是:
using namespace std;
char *man[]={"张三","李四","王五","赵六"};
for(int n=0;n<4;n++)                                                     //每次循环假设n是说假话的人,那么其他三个必须说真话,就是三个条件成立
{if ((n!=0)+(n==2)+(n==3)+(n!=3)==3)                     //n!=0意思是不是第0个说假话(张三)n==2意思是是第2个(即王五)依次类
                                                                                       //推。当三个条件成立时,这个说假话的人就找到了。
cout<<"说假话的人是:"<<man[n]<<endl;}
return 0;

#11


n代表 说谎的,由于不知道谁说谎;
所以假设每个人都有可能说谎,一个一个判断

n==i 代表 说谎的是i
n!=i  代表 说谎的不是i

(n!=0);(n==2);(n==3);(n!=3) 代表4句话  
张山说:不是我。 我就是张山所以这句话 就是“ 说谎的 不是 张山”,代码(索引)为0 就是 n!=0
李四说:是王五。这句话完整的意思是“ 说谎的 王五”,(n==2) 王五代码(索引)为2 
王五说:是赵六。这句话完整的意思是“ 说谎的 赵六”,(n==3) 赵六代码(索引)为3
赵六说:不是我。 我就是赵六所以这句话 就是“ 说谎的 不是 赵六”,代码(索引)为3 就是 n!=3

(n!=0)+(n==2)+(n==3)+(n!=3)==3 代表4句话有3句为真

#12


搞得复杂点
把说的话理解成 
每个人必须这样说
1)是XXX
或者
2)不是XXX
如XXX =我,那么 XXX表示说话者本人
如果XXX是人名 那么XXX表示XXX这个人

这样
这题变成 
wchar_t*  name[] ={L"张山",L"李四",L"王五",L"赵六",L"我"};
wchar_t* sayedes[]={L"不是我",L"是王五",L"是赵六",L",不是我"};
接着定义估值函数
 
int eval(wchar_t *sayed,int sayer,int n)
{
      bool be =1;
      int sayee=0;
       // 分割成两部分
       while(*p!=L’是‘ )
       {
              if(*p==L’不‘)be=0;  
              p++          
       }
      

       //是 be =1,不是 be =0;
      // 我:sayee= sayer,  张山sayee= =0,李四 sayee= 1,王五sayee= =2,赵六sayee= 3
     //好吧简化一下: 
     swtich(*++p){
          case L‘我’:
                 sayee= sayer; break;
           case L‘张’:sayee= 0,break;
           case L‘李’:sayee=1,break; 
           case L‘王’:sayee= 2,break; 
           case L‘赵’:sayee= 3,break;
        }
         return be ? n ==sayee : n!= sayee;               
}

int main(){

     int num =0;
      for(n=0;n<4;n++)
       for(int i=0;i<4;i++){
           num += eval(   sayedes,i,n);
        }
         if(num ==3) {
                    wprintf(L"%s",name[n]);
                    break;
               }
       }
       return 0; 
}

#1


这个题目人脑推理的话也很简单吧,只有一个人说假话,那么立马可以推断在王五和赵六之间,因为他们两个的说法是矛盾的,那么其他两个说的就是对的,所以通过李四就知道是王五说假话

#2


我知道现实中人脑推理很简单,但是我想说的是程序里的那个代码逻辑,我想不通,变量N为什么可以表示循环的同时(在if条件满足的情况下)还正好表示说谎人的指针位置。

#3


引用 1 楼 starytx 的回复:
这个题目人脑推理的话也很简单吧,只有一个人说假话,那么立马可以推断在王五和赵六之间,因为他们两个的说法是矛盾的,那么其他两个说的就是对的,所以通过李四就知道是王五说假话

if里面的那个条件我看不懂,现实中人脑推理简单我知道,我想知道的是if里面那个条件代码的逻辑。

#4


穷举法。n 代表依次试探的说假话的人的下标。注释已经很清楚了,if里面的四个括号分别是4个人各自说真话的判断条件,如果刚好满足3个true的条件,则 n 为所求打印结果。
比如张三的下标是0,那么张三说真话的判断条件就是 n != 0
李四说真话的判断条件是 n == 2 因为 2 是王五的下标。

#5


顶楼上的,他分析的很清楚了。

#6


个人觉得这个代码逻辑没道理,楼主不用去纠结。从代码的if来看已经知道2在说假话了,干嘛还要去判断。而且这里也不存在判断,都已经定死了2是说假话的人。

#7


假设n代表的是说假话的人
一共四个人char *man[]={"张三","李四","王五","赵六"};
for从第一个人开始假设他说的是假话,
如第一次循环,假设张三说的假话。张三说:“不是我”,张三的条件是(n!=0)== false,那么其他三人就应该是真,
但是李四说:“是王五”,条件是(n=2)显然不成立,因此第一次循环条件不成立。
依次类推,进入第二次循环判断,显然也不成立。
进入第三次循环判断,发现王五说的是假话。

#8


个人觉得这个代码逻辑没道理,楼主不用去纠结。从代码的if来看已经知道2在说假话了,干嘛还要去判断。而且这里也不存在判断,都已经定死了2是说假话的人。

#9


引用 楼主 xiji4482 的回复:
张山说:不是我。李四说:是王五。王五说:是赵六。赵六说:不是我。
代码如下:
#include <iostream>
int main()
{
using namespace std;
char *man[]={"张三","李四","王五","赵六"};
for(int n=0;n<4;n++)                                                     //n既为循环控制变量,也表示第N个人
{if ((n!=0)+(n==2)+(n==3)+(n!=3)==3)                     //如果4句话有3句为真,则是该人说假话
cout<<"说假话的人是:"<<man[n]<<endl;}
return 0;
}

求高手解释下变量n的含义。始终想不通。n即是循环次数,又代表说假话的人。逻辑在哪里????


因为man[0]=张三,。。。man[3]=赵六,所以n可以表示说假话的人。
因为是4个人里循环一次,所以n是循环次数

#10


这个问题蛮有意思的,哈哈!
我的理解是:
using namespace std;
char *man[]={"张三","李四","王五","赵六"};
for(int n=0;n<4;n++)                                                     //每次循环假设n是说假话的人,那么其他三个必须说真话,就是三个条件成立
{if ((n!=0)+(n==2)+(n==3)+(n!=3)==3)                     //n!=0意思是不是第0个说假话(张三)n==2意思是是第2个(即王五)依次类
                                                                                       //推。当三个条件成立时,这个说假话的人就找到了。
cout<<"说假话的人是:"<<man[n]<<endl;}
return 0;

#11


n代表 说谎的,由于不知道谁说谎;
所以假设每个人都有可能说谎,一个一个判断

n==i 代表 说谎的是i
n!=i  代表 说谎的不是i

(n!=0);(n==2);(n==3);(n!=3) 代表4句话  
张山说:不是我。 我就是张山所以这句话 就是“ 说谎的 不是 张山”,代码(索引)为0 就是 n!=0
李四说:是王五。这句话完整的意思是“ 说谎的 王五”,(n==2) 王五代码(索引)为2 
王五说:是赵六。这句话完整的意思是“ 说谎的 赵六”,(n==3) 赵六代码(索引)为3
赵六说:不是我。 我就是赵六所以这句话 就是“ 说谎的 不是 赵六”,代码(索引)为3 就是 n!=3

(n!=0)+(n==2)+(n==3)+(n!=3)==3 代表4句话有3句为真

#12


搞得复杂点
把说的话理解成 
每个人必须这样说
1)是XXX
或者
2)不是XXX
如XXX =我,那么 XXX表示说话者本人
如果XXX是人名 那么XXX表示XXX这个人

这样
这题变成 
wchar_t*  name[] ={L"张山",L"李四",L"王五",L"赵六",L"我"};
wchar_t* sayedes[]={L"不是我",L"是王五",L"是赵六",L",不是我"};
接着定义估值函数
 
int eval(wchar_t *sayed,int sayer,int n)
{
      bool be =1;
      int sayee=0;
       // 分割成两部分
       while(*p!=L’是‘ )
       {
              if(*p==L’不‘)be=0;  
              p++          
       }
      

       //是 be =1,不是 be =0;
      // 我:sayee= sayer,  张山sayee= =0,李四 sayee= 1,王五sayee= =2,赵六sayee= 3
     //好吧简化一下: 
     swtich(*++p){
          case L‘我’:
                 sayee= sayer; break;
           case L‘张’:sayee= 0,break;
           case L‘李’:sayee=1,break; 
           case L‘王’:sayee= 2,break; 
           case L‘赵’:sayee= 3,break;
        }
         return be ? n ==sayee : n!= sayee;               
}

int main(){

     int num =0;
      for(n=0;n<4;n++)
       for(int i=0;i<4;i++){
           num += eval(   sayedes,i,n);
        }
         if(num ==3) {
                    wprintf(L"%s",name[n]);
                    break;
               }
       }
       return 0; 
}