码迷,mamicode.com
首页 > 其他好文 > 详细

8.4 智力趣题(1)

时间:2016-07-19 20:38:45      阅读:195      评论:0      收藏:0      [点我收藏+]

标签:

8-13 hanoi1.c

 1 #include <stdio.h>
 2 long count; //全局变量, 记录移动的次数 
 3 void hanoi(int n,char a,char b,char c) //a移到b,用c作临时柱 
 4 {
 5     if(n==1)
 6     {        
 7        printf("第%d次,%c棒-->%c棒\n",++count,a,c);
 8     }
 9     else
10     {
11         hanoi(n-1,a,c,b); //递归调用本函数,移动a到c,用b作临时柱 
12         printf("第%d次,%c棒-->%c棒\n",++count,a,c);
13         hanoi(n-1,b,a,c); //递归调用本函数,将b移到a,用c作临时柱 
14     }
15 }
16 int main()
17 {
18     int h; //圆盘数量 
19     printf("请输入汉诺塔圆盘的数量:");
20     scanf("%d",&h);
21     count=0;
22     hanoi(h,A,B,C);    
23     getch();
24     return 0;
25 }

8-14 hanoi2.c

 1 #include <stdio.h>
 2 #define MAX 64 //最多64个圆盘 
 3 int main()
 4 {
 5    int n, target, source, i, array[(MAX+1)*3+1], stick[3],height;
 6    long count=0;//圆盘移动的次数 
 7    printf("请输入汉诺塔圆盘的数量:");
 8    scanf("%d", &n); //输入盘子数量 
 9    height=n+1;//棒的高度(用来分隔数组) 
10    for (i = 1; i <= n; i++)    //将盘子放入第1个柱子 
11       array[i] = height - i; //数字大的表示大盘子 
12    for (i = 0; i <= 2 * height; i += height)    //将每个柱的底部设置为一个大的数据 
13       array[i] = 1000;
14    if (n % 2 == 0) //若圆盘序号是偶数 
15    {
16       target = 1; //目标为B棒 
17       stick[2] = 0;
18       stick[1] = 1;
19       array[height + 1] = array[n]; //移动第1个圆盘到第2个柱 
20    }
21    else //若圆盘序号为奇数 
22    {
23       target = 2; //目标为C棒 
24       stick[1] = 0;
25       stick[2] = 1;
26       array[2 * height + 1] = array[n]; //移动第1个圆盘到第3个柱 
27    }
28    printf("第%d次,A棒-->%c棒\n",++count,A-1+target+1);  //输出移动操作 
29    stick[0] = n - 1; //A棒中减去一个圆盘 
30    while(stick[0] + stick[1])    //第1棒和第2棒不为空,则循环移动
31    {
32       if (target == 0) //若目标棒是A 
33       {
34           if (array[height + stick[1]] < array[2 * height + stick[2]])//比较B、C柱的较小值作为下一个移动柱 
35               source = 1;
36           else
37               source = 2;
38       }
39       if (target == 1)//若目标棒是B
40       {
41           if(array[stick[0]] < array[2 * height + stick[2]]) //比较A、C柱的较小值 
42               source = 0;
43           else
44               source = 2;
45       }
46       if (target == 2)//若目标棒是C
47       {
48           if(array[stick[0]] < array[height + stick[1]]) //比较A、B柱的较小值 
49               source= 0;
50           else
51               source= 1;
52       }
53 // 将source柱顶部圆盘移到另一较大或为偶数的棒 
54       if ((array[source * height + stick[source]]) > (array[target * height + stick[target]])
55          || ((array[target * height + stick[target]] - array[source * height + stick[source]]) % 2 ==0))
56          target = 3 - source - target;  
57       printf("第%d次,%c棒-->%c棒\n",++count,A-1+source+1,A-1+target+1);  //输出移动操作      
58       stick[source] = stick[source] - 1;
59       stick[target] = stick[target] + 1;    //从source棒移动target棒
60       array[target * height + stick[target]] = array[source * height + stick[source] + 1];
61    }
62    getch();
63    return 0;
64 }

8-15 backpack1.c

 1 #include <stdio.h>
 2 typedef struct goods
 3 {
 4     double *value; //价值
 5     double *weight; //重量
 6     char *select; //是否选中到方案 
 7     int num;//物品数量 
 8     double limitw; //限制重量
 9 }GOODS;
10 double maxvalue,totalvalue;//方案最大价值,物品总价值 
11 char *select1; //临时数组 
12 void backpack(GOODS *g, int i, double tw, double tv)//参数为物品i,当前选择已经达到的重量和tw,本方案可能达到的总价值 
13 {
14    int k;
15    if (tw + g->weight[i] <= g->limitw)//将物品i包含在当前方案,且重量小于等于限制重量 
16    {
17       select1[i] = 1; //选中第i个物品 
18       if (i < g->num - 1) //若物品i不是最后一个物品 
19          backpack(g, i + 1, tw + g->weight[i], tv); //递归调用,继续添加下一物品 
20       else //若已到最后一个物品 
21       {
22          for (k = 0; k < g->num; ++k) //将状态标志复制到option数组中 
23             g->select[k] = select1[k];
24          maxvalue = tv; //保存当前方案的最大价值 
25       }
26    }
27    select1[i] = 0; //取消物品i的选择状态 
28    if (tv - g->value[i] > maxvalue)//若物品总价值减去物品i的价值还大于maxv方案中已有的价值,说明还可以继续向方案中添加物品 
29    {
30       if (i < g->num - 1) //若物品i不是最后一个物品 
31          backpack(g, i + 1, tw, tv - g->value[i]); //递归调用,继续加入下一物品 
32       else //若已到最后一个物品 
33       {
34          for (k = 0; k < g->num; ++k) //将状态标志复制到option数组中 
35             g->select[k] = select1[k];
36          maxvalue = tv - g->value[i]; //保存当前方案的最大价值(从物品总价值中减去物品i的价值)
37       }
38    }
39 }
40 int main()
41 {
42    double sumweight;
43    GOODS g;
44    int i;
45    printf("背包最大重量:");
46    scanf("%lf",&g.limitw);
47    printf("可选物品数量:"); 
48    scanf("%d",&g.num);
49    if(!(g.value = (double *)malloc(sizeof(double)*g.num)))//分配内存保存物品价值 
50    {
51        printf("内存分配失败\n");
52        exit(0); 
53    }
54    if(!(g.weight = (double *)malloc(sizeof(double)*g.num)))//分配内存保存物品的重量 
55    {
56        printf("内存分配失败\n");
57        exit(0);   
58    }
59    if(!(g.select = (char *)malloc(sizeof(char)*g.num)))//分配内存保存物品的重量 
60    {
61        printf("内存分配失败\n");
62        exit(0);   
63    }
64    if(!(select1 = (char *)malloc(sizeof(char)*g.num)))//分配内存保存物品的重量 
65    {
66        printf("内存分配失败\n");
67        exit(0);   
68    }
69    totalvalue=0;   
70    for (i = 0; i < g.num; i++)
71    {
72       printf("输入第%d号物品的重量和价值:",i + 1);
73       scanf("%lf%lf",&g.weight[i],&g.value[i]);
74       totalvalue+=g.value[i];//统计所有物品的价值总和 
75    }
76    printf("\n背包最大能装的重量为:%.2f\n\n",g.limitw);
77    for (i = 0; i < g.num; i++)
78       printf("第%d号物品重:%.2f,价值:%.2f\n", i + 1, g.weight[i], g.value[i]);
79    for (i = 0; i < g.num; i++)//初始设各物品都没加入选择集 
80        select1[i]=0;
81    maxvalue=0;//加入方案物品的总价值 
82    backpack(&g,0,0.0,totalvalue); //第0号物品加入方案,总重量为0,所有物品价值为totalvalue 
83    sumweight=0; 
84    printf("\n可将以下物品装入背包,使背包装的物品价值最大:\n");
85    for (i = 0; i < g.num; ++i)
86       if (g.select[i])
87       {
88          printf("第%d号物品,重量:%.2f,价值:%.2f\n", i + 1, g.weight[i], g.value[i]);
89          sumweight+=g.weight[i];
90       }     
91    printf("\n总重量为: %.2f,总价值为:%.2f\n", sumweight, maxvalue );
92    getch();
93    return 0;
94 }

 

8.4 智力趣题(1)

标签:

原文地址:http://www.cnblogs.com/wozixiaoyao/p/5686045.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!