在阅读代码前,先说一下这本书的在版编目(CIP)数据:C语言程序设计教程/黄迪明、余勤主编.--北京:国防工业出版社,2006.5 ISBN 7-118-04516-0
所有代码均在 VS2013 中成功运行。若有不妥之处,非常欢迎您提出问题,若能提出改进意见,不胜感激!
4.1 将一个数组中的值按逆序存放。例如,原来是8,5,4,6,1, 要求改为1,6,4,5,8。
提示:要将一个数组中的所有元素按逆序存放,只需将数组中的第一个元素与最后一个元素交换,第二个元素与倒数第二个元素交换,直到数组最中间元素即可。
#include<stdio.h>
void main()
{
printf(" 将一个数组中的值按逆序存放。例如,原来是8,5,4,6,1, 要求改为1,6,4,5,8.\n\n");
int N = 0, *p, i = 0;
printf("请输入要排序的个数:");
scanf("%d", &N);
p = (int *)malloc(sizeof(int)*N);
for (i = 1; i <= N; i++)
{
printf("请输入第 %d 个数:", i);
scanf("%d", &p[i - 1]);
}
for (i = N; i >= 1; i--)
{
printf("%5d", p[i - 1]);
}
getch();
}
4.2 N盏灯排成一排,从1到N编号。也有N个人从1到N依次编号。第一个人(1号)将灯全部打开,第二个人(2号)将2和凡是2的倍数的灯关闭。第三个人(3号)将凡是3和3的倍数的灯做相反的处理(即将打开的灯关闭,将关闭的灯打开),以后的人都和3号一样,将凡是与自己编号相同的灯和自己编号倍数的灯做相反处理,请问当第N个人操作之后,哪盏灯是亮的?试编程求解这个问题,N由键盘输入。
提示:这个题与筛法求素数类似。
用一维数组lamp表示每盏灯的状态,lamp[i]=0表示第i盏灯是关闭的,为1表示第i盏灯是打开的。开始时所有的灯都是关闭的,所以把lamp数组的所有元素赋值为0.
接下来,用一个一重循环依次处理每个人的操作:for(i=1;i<=n;i++),其中i表示当前操作者的编号。根据题意,第i号人要让第i盏灯和与i有倍数关系的灯改变状态。因此在处理某个人的操作时,再用一重循环:for(j=1;j<=n;j++),其中j表示灯的编号。这里要改变状态即实现0和1之间的转变。
最后用一个一重循环输出结果
#include<stdio.h>
void main()
{
printf("N盏灯排成一排,从1到N编号。也有N个人从1到N依次编号。第一个人(1号)将灯全部打开,第二个人(2号)将2和凡是2的倍数的灯关闭。\n第三个人(3号)将凡是3和3的倍数的灯做相反的处理(即将打开的灯关闭,将关闭的灯打开),\n以后的人都和3号一样,将凡是与自己编号相同的灯和自己编号倍数的灯做相反处理,\n请问当第N个人操作之后,哪盏灯是亮的?试编程求解这个问题,N由键盘输入。\n\n");
int i, j, n = 8, people;//设共有8盏灯
int deng[8];
for (i = 0; i < n; i++) //先设每盏灯的情况为灭灯
{
deng[i] = 0;
}
for (j = 1; j <= n; j++) //从第一盏灯开始处理
{
for (people = j; people <= n; people++) //第n盏灯对应的第n个人
for (i = j; i <= n; i = i + j)
{
if (deng[i - 1] == 0)
deng[i - 1] = 1;
else
deng[i - 1] = 0;
}
}
for (i = 1; i <= n; i++)
{
if (deng[i - 1] == 1)
printf("第\t%d\t盏灯是亮的\n", i);
}
getch();
}
4.3 用简单选择法对10个整数进行排序。
提示:选择排序是不断在待排序序列(无序区)中按递增(或递减)次序选择记录,放入有序区,逐渐扩大有序区,直到整个记录表去为有序区为止。
其基本思想是:每一趟(例如第i趟,i=1,2,...,n-1)在后面n-i个待排序对象中选择出最小的一个,作为有序序列的第i个。待第n-1趟做完,待排序只剩一个对象了,就不用选了。
#include<stdio.h>
#define n 8
void main()
{
printf("用简单选择法对10个整数进行排序。");
int i,a, b, temp, changed = 0;
int px[n];
for ( i = 1; i <=n; i++)
{
printf("请输入第%d个整数:",i);
scanf("%d",&px[i-1]);
}
for ( a = 1; a < n; a++) //第a趟
{
for ( b = 1; b <=n-a; b++) //第b次比较
{
if (px[b-1]>px[b])
{
temp = px[b - 1];
px[b - 1] = px[b];
px[b] = temp;
changed = 1;
}
}
if (changed==0)
{
break;
}
else if (changed==1)
{
changed = 0;
}
}
printf("排序后的数为:\t");
for ( i = 1; i <=n; i++)
{
printf("%d\t",px[i-1]);
}
getch();
}
4.4 所谓幻方,就是一个n行n列的正方形,当n为奇数时,就成为奇数阶幻。共有n^2个格子,将1,2,3,...,n^2这些数字放在这些格子里,使其每行每列的和及两条对角线的和都是同一个数。试编程由键盘输入一个奇数n,输出一个n阶幻方。
提示:多少年来,许多科学家都在研究这个古老而有趣的问题,试图找出一般的做法,但仅仅找出了n是奇数和是4的倍数的情况。现在介绍n是奇数时的解法。
(1)将1放在第一行中间一个格子里。
(2)依次将后一个数放在前一个数的右上格,如将2放在1的右上格,将3放在2的右上格等。可能会出现下面的情况:
1. 若右上格从上面超出,则将后一个数放在与右上格同列的最后一行。
2.若右上格从右面超出,则将后一个数放在与右上格同行的第一列。
3.若右上格既从上面超出又从右面超出,则将后一个数放到前一个数的下面。
4.若右上格已被数字填充,则将后一个数放到前一个数的下面。
#include<stdio.h>
void main()
{
printf(" 所谓幻方,就是一个n行n列的正方形,当n为奇数时,就成为奇数阶幻。共有n^2个格子,将1,2,3,...,n^2这些数字放在这些格子里,\n使其每行每列的和及两条对角线的和都是同一个数。试编程由键盘输入一个奇数n,输出一个n阶幻方。\n\n");
int a, b, n, i, row, col;
int hf[99][99] = { 0 };
printf("请输入您要的幻方矩阵(n必须为奇数):");
scanf("%d", &n);
if (n % 2 == 0)
{
printf("无法输出该偶数的幻方矩阵,请输入奇数");
}
else
{
a = 0;
b = n / 2;
hf[a][b] = 1;
for (i = 2; i <= n*n; i++)
{
if (