高效的算法:http://blog.youkuaiyun.com/qq_36238595/article/details/53885311
我的想法完全是最直接的模拟。
南阳的思路:
将abcde看成0到4的5个数,从0开始(也就是a开始)假设是他扶的,则必须满足所有人说的话的条件,因为只有两个人说的是真话,所以满足条件的次数只能是2次。
我的思路:要先找出(枚举)讲真话人的组合,再根据组合所形成的条件限制,再一一假设五个人扶了老奶奶,再看是否能通过已经形成的条件限制
他的思路是从结果推导至条件,我是设定条件去检验结果,而设定条件又是从附属的结果讲真话的人来的。
答案是 A B E ,然而我写的算法得出来的答案是A E B,结果就没有通过,这是第四次提交了,不知道为什么就改过来了,把A E B改成A B E。 可能是相信自己不至于弱智到这种程度改了n次还得不出正确答案吧。orz,可怕的老奶奶。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
int main()
{
int a,b,c,d,e,nn[6],i,j;
for(a=0;a<=1;a++)/*五人对错大循环*/
for(b=0;b<=1;b++)
for(c=0;c<=1;c++)
for(d=0;d<=1;d++)
for(e=0;e<=1;e++)
{
if((a+b+c+d+e)!=2) continue;/*两个人讲真话*/
for(i=1;i<=5;i++)/*根据谁扶老奶奶来做对五个人的话真假性的判断循环*/
{
memset(nn,0,6*sizeof(int));/*每一次都要重置,放在外面的话,会出现五个人都扶老奶奶的情况,因为nn[1]=1之后没有清零,nn[2]又变成一了……*/
nn[i]=1;
if(a)/*用假设成立的条件取反*/
{
if(!(nn[1]==0&&nn[5]==0)) continue;
}
else/*用假设不成立的条件取反*/
{
if(!(nn[1]==1||nn[5]==1)) continue;
}
if(b)/*因为这样要转的弯只有0或1层*/
{
if(!(nn[3]==1||nn[5]==1)) continue;
}
else/*而且不容易搞乱*/
{
if(!(nn[3]==0&&nn[5]==0)) continue;
}
if(c)
{
if(!(nn[3]==1||nn[4]==1)) continue;
}
else
{
if(!(nn[3]==0&&nn[4]==0)) continue;
}
if(d)
{
if(!(nn[3]==0&&nn[2]==0)) continue;
}
else
{
if(!(nn[3]==1||nn[2]==1)) continue;
}
if(e)
{
if(!(nn[5]!=1)) continue;
}
else
{
if(!(nn[5]==1))continue;
}
for(j=1;j<=5;j++)
{
if(nn[j]) printf("%c ",64+j);
}
}
}
return 0;
}