聪明的学生C语言实现(栈)

不写初中高级这种实验啦 直接上STL吧 /如果有不懂的话可以看看STL容器,我直接给个百度百科的链接吧https://baike.baidu.com/item/STL/70103?fr=aladdin/

聪明的学生(实验名称)
一、实验目的
掌握递归思想,将“聪明的学生”问题抽象出递归并加以实现。

二、实验内容
(1)将“聪明的学生”问题抽象为递归算法。
(2)键盘输入三个数字,要求输出谁能猜出,并输出递归过程的中间数据。 (3)给出测试用例:3,8,5 的输出结果。

三、提示参考
提示 1:总是帖着最大数的那个人猜出了自己头上的数。
提示 2:将“聪明的学生”问题抽象为递归思想,特别注意递归程序的两个 方面是递归出口和迭代步骤。
问题分析:依题可知,每个学生都能知道其他另外两个学生的数字,但不清楚自己数字。假设,我们以 1,2,3,作为例子来分析。A 只有两种情况,一种是(21),另外一种是(2+1),但是 A 自己不能确定是哪一种情况,所以 A 猜不出来。 再来看看 B,两种情况是(1+3)或者(3-1),但是 B 仍然不能确定,最后是 C, 两种情况是(1+2)或者(2-1),但是 C 是可以排除(2-1)这种情况的,因为如 果 C 是(2-1),那么 B 是在看到 A 是 1,C 是 1 的情况下,B 可以猜出来自己是 2,但是 B 没有猜出来,故而 C 可以排除是( 2-1)这种情况,因而 C 只能是( 2+1), 也就是 3。可以分析总结出最大的数字总会最先猜出来,是因为只有最大的数字 是可以排除相减的情况的,因为如果它是相减得到的话,前面一定有人可以猜出 来。 现在,我们将问题抽象。即 A,B,C 三个学生,他们头上的数字分别为 x1,x2,x3。 从上述结论可知,最大的数总会被最先猜出来。不妨假设,B 是最先猜出来的学 生,即 x2 = x1+x3.而 B 能排除|x1-x3|这种可能性的依据有两个,一是 x1=x3,那 么 B 只能是 x1+x3,因为三个都是正整数。另外一种依据是假设在 x2=|x1-x3|的 前提下,那么在前面的提问中,A 或者 C 已经先猜出来了,而因为他们没有猜出 来,让自己可以确定自己是两数之和,而非两数之差。可以结合上面 1,2,3 去看。 而是 A 先猜出来还是 C 先猜出来,如果 A>C,那么 A 先猜出来,反之,C 会先猜 出来。 那么问题,可以转化为,找出 x1,|x1-x3|,x3 中第一个猜出数字的人所用的 次数。这个问题不断的重复成一个子问题,不断的重复这个过程,直到某个学生 能够猜出这个数字来。这样可以归结为如下的一个递归函数:
这里写图片描述
其中,T1 编号的人头上数字为 I,T2 编号的人头上数字为 J,编号 T3 的头上数字 为 I+J(即 T3 将最先猜出来自己的数字),教授提问的次数是 P(T1,T3),表示按照 12-3 的顺序,从 T1 问到 T3 所用的最少次数。请同学们根据该递归函数,写出代 码实现。

四、实验代码(包括运行结果截图)

1.  #include<stdlib.h>  
2.  #include<stdio.h>  
3.    
4.  //找出t1到t2的最小提问次数  
5.  int step(int t1, int t2)  
6.  {  
7.      if (t2 > t1)  
8.          return (t2 - t1);  
9.      else  
10.         return (t2 + 3 - t1);  
11. }  
12.   
13. //教授提问多少次时t3能够回答  
14. int times(int i,int j,int t1,int t2,int t3)  
15. {  
16.     int k;  
17.     k = i - j;  
18.     if (k == 0)  
19.         return t3;  
20.     else if (k > 0)  
21.         return times(j, i - j, t2, t3, t1) + step(t1, t3);  
22.     else  
23.         return times(i, j - i, t1, t3, t2) + step(t2, t3);  
24. }  
25.   
26. int main()  
27. {  
28.     int result;  
29.     int a, b, c, i;  
30.     int array[3];//与上面的结果一样整倍关系  
31.     int index = 0;  
32.     int max_num, mid_num;//保留存储第一大和第二大的数  
33.     int max_index, mid_index;//保留存储第一大和大二大的数的下标  
34.   
35.     while (1) {  
36.         a = 1; b = 2; c = 3;  
37.         max_num = -1; mid_num = -1;//保留存储第一大和第二大的数  
38.         max_index = -1; mid_index = -1;//保留存储第一大和大二大的数的下标  
39.         for (i = 0; i < 3; i++)  
40.             scanf_s("%d", &array[i]);  
41.         for (index = 0; index < 3; index++)  
42.         {  
43.             if (max_num < array[index])  
44.             {  
45.                 mid_num = max_num;  
46.                 mid_index = max_index;  
47.                 max_num = array[index];  
48.                 max_index = index;  
49.             }  
50.             if (mid_num < array[index] && array[index] != max_num)  
51.             {  
52.                 mid_num = array[index];  
53.                 mid_index = index;  
54.             }  
55.   
56.         }  
57.         c = max_index + 1;  
58.         b = mid_index + 1;  
59.         //找出最小的代码  
60.         if ((c == 1 && b == 2) || (c == 2 && b == 1))  
61.             a = 3;  
62.         else if ((c == 2 && b == 3) || (c == 3 && b == 2))  
63.             a = 1;  
64.         else  
65.             a = 2;  
66.         //调用递归函数,第一个参数为最小数,第二个参数为中间数  
67.         //a为最小值编号,b为中间值编号,c为最大值编号  
68.         result = times(array[a - 1], array[b - 1], a, b, c);//3 5 8 answer:6  
69.         printf("result=%d\n", result);  
70.     }  
71.     return 0;  
72. }  

这里写图片描述

猜你喜欢

转载自blog.csdn.net/Around_corner/article/details/78508807