C语言实现小时候经常做的智力测试题

   
下面的是两道面试题,小时候经常会看到这种类似的题目,但是用C语言实现,确实没那么容易想到,尤其是对我这种接触C语言仅仅一年的新人。

     话不多说, 先上题………..

1、

 

 

5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果

A选手说:B第一,我第三。

B选手说:我第二,E第四。

C选手说:我第一,D第二。

D选手说:C最后,我第三。

E选手说:我第四,A第一。

比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。

 

#include<stdio.h>

int main()
{
 int a = 0;
 int b = 0;
 int c = 0;
 int d = 0;
 int e = 0;
 for (a = 1; a <= 5; a++)
 {
  for (b = 1; b <= 5; b++)
  {
   for (c = 1; c <= 5; c++)
   {
    for (d = 1; d <= 5; d++)
    {
     for (e = 1; e <= 5; e++)
     {
      if (((b == 1) + (a == 3) == 1) && ((b == 2) + (e == 4) == 1) && ((c == 1) + (d == 2) == 1) && ((c == 5) + (d == 3) == 1) && ((e == 4) + (a == 1) == 1))
      {
       printf("A:第%d名  B:第%d名  C:第%d名  D:第%d名  E:第%d名\n",a,b,c,d,e);
      }
     }
    }
   }
  }
 }

 system("pause");
 return 0;
}

 

 

 2、

日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。以下为4个嫌疑犯的供词。

A说:不是我。

B说:是C。

C说:是D。

D说:C在胡说

已知3个人说了真话,1个人说的是假话。

现在请根据这些信息,写一个程序来确定到底谁是凶手。

 

#include<stdio.h>

int main()
{
 int  kill = 0;
 for (kill = 'a'; kill <= 'd'; kill++)
 {
  if ((kill != 'a') + (kill == 'c') + (kill == 'd') + (kill != 'd') == 3)
  {
   printf("杀手是%c\n",kill);
  }
 }
 system("pause");
 return 0;
}

 

 

 

 

看完之后,才发现并没有自己想的那么复杂。总是重复纠结一些问题,导致没有办法去想整体的方法。下面我就简单总结一下我解决这类实际问题的方法吧。

     1、  
让C语言解决实际问题,其实它是特别笨的,它不能够去分析逻辑找捷径(或者说我们还不会用它找捷径),所以
  while   或    for  
 循环语句是必要的,它得把所有可能的情况一个一个列出来进行分析,看是否符合它的要求,再把符合要求的情况
  printf  出来。

       
第一题,判断五个人的排名,那么输出结果必然是五个人,每个人的名次可能是1-5,那么就有25种情况,嵌套5个for循环语句可以实现这一功能。

     
 第二题,需要判断谁是killer,很明显,程序只需要输入killer是谁就可以,也就是一个人,而其他的人就必然是无关人。因此,有4个嫌疑人,就需要4次循环,每次假设某一个人为killer,一次循环就可以做到列出谁是killer的所有情况。(由于四个人是abcd,所以定义了int型变量,从’a’到‘d’,字符型在内存里是以整型存储的。)

       2、列出所有情况之后就要对所有情况进行判断,   if  
语句,判断是否满足条件。到了第二个难点,条件怎么写。

       
第一题,五个人,每个人说的都有一真一假,也就是说,一个人说两句话只有一句是真话,“A选手说:B第一,我第三。”两个条件分别是(b==1)(a==3),中间怎么连接呢? 

                    &&:都为真,结果为1          
 ||:有一个为真结果就为1   而
!考虑多种可能的话程序又会很复杂。这里用先+再判断是否==1,(b==1)+(a==3)==1,两个条件只有一个为真是结果为真,要求五个人说的话都满足,所以五个语句之间用&&连接。只要用循环语句列出来的情况同时满足五个人说的话(只有一句话是真话),则这种情况符合题意,直接输出,然后再次判断下一种情况。

     
 第二题,四个人说的话只有三个人是真的,计算量相当于只有第一题的五分之一,只要判断四个满足三个条件,第四个不满足就可以,而不用多个用&&再连接。

         if ((kill != ‘a’) + (kill == ‘c’) + (kill == ‘d’) + (kill !=
‘d’) ==
3)四个人说的四种情况相加,结果等于三时,说明只满足三个条件,第四个不满足,当某一个嫌疑人是killer时
 if  语句成立,则该嫌疑人确定为killer,输出。

下面的是两道面试题,小时候经常会看到这种类似的题目,但是用C语言实现,确实没那么容易想到,…

思路:

每个学校的名次是1~5范围之间,所以采用5个for var=1 to
5的循环来表示每个学校的可能名次(这算是暴力破解吧,还请大神指正另外的思路)。在最内层循环中,利用if条件判断语句描述题目中的说法,例如:((c
== 1) || (c == 2)) && (a ==
5),该语句表示c若满足是第一名或第二名,那么c说的是真话,a此时就应该是最差的。比较特殊的有:1、(a
== 2) && (e == 1),这是因为a == 1,若为真的话,e就不能为1;2、b ==
2,b自己说自己是第二,要么是真话,要么是假话,也不能匹配其他条件。剩余的两个条件相信大家也能类似的推出来。

那么在这几个判断条件中,只有两个人说了真话,所以将这5个判断条件相加应该等于2,表示这五个条件中,有2个人说了真话。

进入if条件中后,我们用val的五个位分别表示每个学校可能的名次,只有满足val的后5位是全1的才能说明a、b、c、d、e分别隶属于不同的名次,不然肯定有某几个学校的名次是重合的。接下来我们就用while(val)循环判断val的后5位是否是全1。flag标志为0表示后5位某一位为0,不满足我们的条件。cnt是确保确实while循环执行了5次,因为在测试的过程中发现,仅根据flag标识会漏判末尾连续全1,但高位存在0的情况,比如:00001。

当判断最后5位全1的条件满足时,我们就输出符合条件的情况:

图片 1

include <stdio.h>

void main()
{
int i;
for(i=1;i<=5;i++)
{
printf(“xxx\n”);
break;//结束整个循环,转而执行循环后面的语句
printf(“vvv\n”);
}
printf(“bbb\n”);
}
练习:统计从键盘输入的有效字符的个数,就是第一个空格键之前的字符,如果没有空格符,就是回车之前的所有字符。

代码:

#include <stdio.h>

int main() {
    int a, b, c, d, e;
    int val = 0;
    int flag = 1;
    int cnt = 0;
    for(a = 1; a <= 5; a++)
        for(b = 1; b <= 5; b++)
            for(c = 1; c <= 5; c++)
                for(d = 1; d <= 5; d++)
                    for(e = 1; e <= 5; e++)
                        if(((a == 2) && (e == 1)) + 
                                (b == 2) + 
                                (((c == 1) || (c == 2)) && (a == 5)) + 
                                (((d == 1) || (d == 2)) && (c != 1)) + 
                                (((e == 1) || (e == 2)) && (d == 1))
                                    == 2) {
                            val = 0;
                            flag = 1;
                            cnt = 0;

                            val |= (1 << (a-1));
                            val |= (1 << (b-1)); 
                            val |= (1 << (c-1));
                            val |= (1 << (d-1));
                            val |= (1 << (e-1));
                            while(val) {
                                if(val%2 == 0) 
                                    flag = 0;
                                val /= 2;
                                cnt++;
                            }
                            if(flag == 1 && cnt == 5) {
                                printf("a=%d b=%d c=%d d=%d e=%d\n", a, b, c, d, e);
                            }
                        }
    return 0;
}

include <stdio.h>

void main()
{
int A,B,C,D,E;
for(A=1;A<=5;A++)
for(B=1;B<=5;B++)
for(C=1;C<=5;C++)
for(D=1;D<=5;D++)
for(E=1;E<=5;E++)
if((B==1)+(A==3)==1 &&
(B==2)+(E==4)==1 &&
(D==3)+(C==5)==1 &&
(C==1)+(D==2)==1 &&
(E==4)+(A==1)==1)
printf(“A:%d B:%d C:%d D:%d E:%d\n”,A,B,C,D,E);
}

猴子吃桃:猴子第一天的时候摘了若干个桃子,当即吃了一半多一个,第二天又吃了剩下的一半多一个,以后每天都吃剩下的一半多一个,等到第6天想吃桃子的时候,发现只剩下一个,问第一天一共摘了多少个桃子。
6:1
5:(1+1)2
4:(day5+1)
2
=> day前=(day今+1)2
=>n=(n+1)
2

题目描述:

A、B、C、D、E五个学校,A说E是第一,B说B是第二,C说A是最差的,D说C不是最好的,E说D是最好的。只有第一和第二名说的是对的,其他说的都是错的,请编程确定五个学校的名次。

先上代码,再说思路。

include <stdio.h>

void main()
{
int m=1,sum,i,n=1;
// while(1)
// {
// m=n;
// sum=n;
for(n=1;n<10;n++)
{
m=n;
sum=n;
for(i=7;i>=1;i–)
{
m=m*2;
sum=sum+m;
}
// printf(“sum=%d\n”,sum);
if(sum==765)
{
printf(“m=%d n=%d\n”,m,n);
break;//跳出循环
}
// printf(“m=%d\n”,m);
// n++;
}

}
自由落体:有一个小球从100米的高度自由落下,反弹回原高度的一半继续落下,以后重复如此,问:第十次落下的时候共经过多少米,然后弹回多高的距离?

include <stdio.h>

void main()
{
float h=100,sum=0,i;
for(i=1;i<=9;i++)
{
h=h/2;
sum=sum+3*h;
}
printf(“sum:%.1f h:%.1f\n”,sum,h/2);
}

continue:结束当前循环,进入下一次循环

include <stdio.h>

void main()
{
int d,n=1;
for(d=5;d>=1;d–)
n=(n+1)*2;
printf(“n=%d\n”,n);
}

百钱买百鸡:一百块买一百鸡,3/公,2/母,2只/块。
问:怎样一百块钱买一百只鸡。

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注