《C语言程序设计教程》(主编黄迪明、余勤)第四章课后习题答案

       在阅读代码前,先说一下这本书的在版编目(CIP)数据:C语言程序设计教程/黄迪明、余勤主编.--北京:国防工业出版社,2006.5    ISBN 7-118-04516-0

       所有代码均在 VS2013 中成功运行。若有不妥之处,非常欢迎您提出问题,若能提出改进意见,不胜感激!


4.1  将一个数组中的值按逆序存放。例如,原来是8,5,4,6,1, 要求改为1,6,4,5,8。

       提示:要将一个数组中的所有元素按逆序存放,只需将数组中的第一个元素与最后一个元素交换,第二个元素与倒数第二个元素交换,直到数组最中间元素即可。

#include
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
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
#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
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 (((a - 1)<0) && (((b + 1) <= (n - 1)) && (b + 1 >= 0)))
			{
				a = n - 1;
				b = b + 1;
				hf[a][b] = i;
			}
			else if ((((a - 1) <= (n - 1)) && (a - 1 >= 0)) && ((b + 1)>(n - 1)))
			{
				a = a - 1;
				b = 0;
				hf[a][b] = i;
			}
			else if ((((a - 1) <= (n - 1)) && (a - 1 >= 0)) && (((b + 1) <= (n - 1)) && (b + 1 >= 0)) && (hf[a - 1][b + 1] != 0))
			{
				a = a + 1;
				b = b;
				hf[a][b] = i;
			}
			else if ((((a - 1) <= (n - 1)) && (a - 1 >= 0)) && (((b + 1) <= (n - 1)) && (b + 1 >= 0)) && (hf[a - 1][b + 1] == 0))
			{
				a = a - 1;
				b = b + 1;
				hf[a][b] = i;
			}
			else if ((a - 1<0) && (b + 1>n - 1))
			{
				a = a + 1;
				b = b;
				hf[a][b] = i;
			}
		}
		for (row = 1; row <= n; row++)
		{
			for (col = 1; col <= n; col++)
			{
				printf("%3d\t", hf[row - 1][col - 1]);
			}
			printf("\n");
		}
		getch();
	}
}

4.5  输入一个字符串,要求按照相反的顺序输出各个字符。例如,输入: AbcD,则输出为: DcbA

       提示:这个题与习题4.1类似,但需注意的是:

          (1)存储要输入的字符串的数组的长度要足够大。

          (2)存储字符串数组与字符串长度之间的关系。

#include
#include
void main()
{
	printf("输入一个字符串,要求按照相反的顺序输出各个字符。例如,输入: AbcD,则输出为: DcbA.");
	char shuzu[100];
	int i, len;
	printf("请输入要排序的字符串: ");
	gets(shuzu);
	len = strlen(shuzu);
	printf("\n排序好(逆序)的字符串为: ");
	for (i = len; i >= 1; i--)
	{
		printf("%c", shuzu[i - 1]);
	}
	getch();
}

4.6  输入一行字符,统计其中包含多少个单词,单词之间用空格分隔。

        提示:单词的数目可以由空格出现的次数决定(连续的若干个空格作为一个空格,一行开头的空格不统计在内)。因此,本题的关键是如何对连续的空格进行处理。这可以设置一个变量sapce来表示,当读入到第一个空格时,将sapce的值置为1,表示读到了空格,以后再读到空格时判断sapce的值是否为1,以此确定是否为连续空格,若不是连续空格,则单词数加1;读到非空格时,将space置为0,space的初始值为1.

#include
void main()
{
	printf(" 输入一行字符,统计其中包含多少个单词,单词之间用空格分隔。");
	char word[100];
	int geshu = 0, zimu = 0;
	int i,len;
	printf("请输入一串字符: ");
	scanf("%s",word);
	len = strlen(word);
	for ( i = 1; i <= len; i++)
	{
		if (word[i-1]!=' ')
		{
			zimu = zimu + 1;
		}
		else
		{
			if (zimu>0)
			{
				geshu = geshu + 1;
				zimu = 0;
			}
		}
	}
	printf("共有的单词数: %d",geshu);
	getch();
}

4.7  编写一个学生管理系统,其中学生的信息有姓名(汉字或汉语拼音,最多20个字符),性别(用0表示男,1表示女),生日(19850101(年月日)),身高(1.74(m)),还要处理C语言、微积分两门课的成绩,请编写程序实现以下功能:

        首先从键盘输入学生的人数,然后依次输入每个学生的数据,输出每门课的总平均分,最高分,最低分,以及获取最高分的学生的信息。注意,获取最高分的学生可能不止一个。

#include
#include
struct date
{
	int year;
	int month;
	int day;
};
struct student
{
	char name[21];
	int sex;
	struct date birthday;
	float height;
	int cyuyan;
	int weijifen;
};
void main()
{
	printf("编写一个学生管理系统,其中学生的信息有姓名(汉字或汉语拼音,最多20个字符),\n性别(用0表示男,1表示女),生日(19850101(年月日)),身高(1.74(m)),还要处理C语言、微积分两门课的成绩,\n请编写程序实现以下功能:首先从键盘输入学生的人数,然后依次输入每个学生的数据,输出每门课的总平均分,最高分,最低分,\n以及获取最高分的学生的信息。注意,获取最高分的学生可能不止一个。\n\n");
	int n = 0;
	printf("请输入学生的人数:");
	scanf("%d", &n);
	struct student *pt;
	pt = (struct student*)malloc(sizeof(struct student)*(n + 1));
	int i = 0;
	int weisum = 0, weihei, weilow;
	int csum = 0, chei, clow;
	float weiave = 0, cave = 0;
	for (i = 1; i <= n; i++)
	{
		printf("\n请输入第%d个学生的信息", i);
		printf("\n姓名:");
		scanf("%s", &pt[i].name);
		printf("\n性别(0男 1女):");
		scanf("%d", &pt[i].sex);
		printf("\n出生年龄\n");
		printf("年份:");
		scanf("%d", &pt[i].birthday.year);
		printf("月份:");
		scanf("%d", &pt[i].birthday.month);
		printf("日期:");
		scanf("%d", &pt[i].birthday.day);
		printf("身高:");
		scanf("%f", &pt[i].height);
		printf("C语言成绩:");
		scanf("%d", &pt[i].cyuyan);
		printf("微积分成绩:");
		scanf("%d", &pt[i].weijifen);
	}
	weihei = pt[1].weijifen;
	weilow = pt[1].weijifen;
	chei = pt[1].cyuyan;
	clow = pt[1].cyuyan;
	for (i = 1; i <= n; i++)
	{
		if (cheipt[i].cyuyan)
		{
			clow = pt[i].cyuyan;
		}
		csum = csum + pt[i].cyuyan;
		if (weiheipt[i].weijifen)
		{
			weilow = pt[i].weijifen;
		}
		weisum = weisum + pt[i].weijifen;
	}
	cave = (float)csum / n;
	weiave = (float)weisum / n;
	printf("C语言课程的总平均成绩为:%f,最高分为:%d,最低分为:%d\n", cave, chei, clow);
	printf("获得C语言最高分的学生的姓名:\n");
	for (i = 1; i <= n; i++)
	{
		if (chei == pt[i].cyuyan)
		{
			printf("%s\n", pt[i].name);
		}
	}
	printf("微积分课程的总平均成绩为:%f,最高分为:%d,最低分为:%d\n", weiave, weihei, weilow);
	printf("获得微积分最高分的学生的姓名:\n");
	for (i = 1; i <= n; i++)
	{
		if (weihei == pt[i].weijifen)
		{
			printf("%s\n", pt[i].name);
		}
	}
	getch();
}

4.8  在用C语言编程求图像问题时,常用结构表示平面上的点,试编程求解以下问题:

      (1)输入两个点的坐标,求这两点间的距离。

      (2)输入三个点的坐标,判断这三个点是否共线。

      (1)

#include
#include
void main()
{
	printf("输入两个点的坐标,求这两点间的距离。\n\n");
	float c[2][2] = { 0 };
	printf("请输入第一个点的坐标:");
	scanf("%f%f",&c[0][0],&c[1][0]);
	printf("请输入第二个点的坐标:");
	scanf("%f%f", &c[0][1], &c[1][1]);
	printf("两点间的距离为:%f", sqrt((c[0][0] - c[0][1])*(c[0][0] - c[0][1]) + (c[1][0] - c[1][1])*(c[1][0] - c[1][1])));
	getch();
}
      (2)

#include
void main()
{
	float c[2][3] = { 0 };
	printf("请输入第一个点的坐标:");
	scanf("%f%f", &c[0][0], &c[1][0]);
	printf("请输入第二个点的坐标:");
	scanf("%f%f", &c[0][1], &c[1][1]);
	printf("请输入第三个点的坐标:");
	scanf("%f%f", &c[0][2], &c[1][2]);
	if ((c[1][0] - c[1][1]) / (c[0][0] - c[0][1]) - (c[1][0] - c[1][2]) / (c[0][0] - c[0][2])<0.001)
	{
		printf("这三点共线.");
	}
	else
	{
		printf("这三点不共线.");
	}
	getch();
}

4.9用数组存放图书的信息,每本书包括书名、作者、出版社、出版日期、借出数目、库存数目等信息。编写程序存放若干本图书的信息,按照书名排序后输出。

      提示:注意,这里是要对书名排序,而书名是字符串,要用字符串比较函数strcmp(),而不是直接对两个字符串进行比较。

#include
#include
struct birthday
{
	int year;
	int month;
	int day;
};
struct books
{
	char name[21];
	char author[21];
	struct birthday time;
	char deriv[21];
	int lend;
	int reser;
};
void main()
{
	printf("用数组存放图书的信息,每本书包括书名、作者、出版社、出版日期、借出数目、库存数目等信息。\n编写程序存放若干本图书的信息,按照书名排序后输出。\n\n");
	struct books *pt;
	int n = 0,i=0,j=0,k=0;
	printf("请输入书名的本数:");
	scanf("%d",&n);
	pt = (struct books *)malloc(sizeof(struct books)*(n + 1));
	for ( i = 1; i <= n; i++)
	{
		printf("\n\n请输入第 %d 本书的信息:",i);
		printf("\n请输入书名:");
		scanf("%s",pt[i].name);
		printf("请输入作者:");
		scanf("%s",pt[i].author);
		printf("请输入请输入出版的年份:");
		scanf("%d",&pt[i].time.year);
		printf("请输入请输入出版的月份:");
		scanf("%d", &pt[i].time.month);
		printf("请输入请输入出版的日期:");
		scanf("%d", &pt[i].time.day);
		printf("请输入出版社的名称:");
		scanf("%s",pt[i].deriv);
		printf("请输入该图书借出的数目:");
		scanf("%d",&pt[i].lend);
		printf("请输入该图书库存数目:");
		scanf("%d",&pt[i].reser);
	}
	for ( i = 1; i < n; i++)
	{
		k = i;
		for ( j = i+1; j <= n; j++)
		{
			if (strcmp(pt[k].name,pt[j].name)>0)
			{
				k = j;
			}
		}
		if (k!=i)
		{
			pt[0] = pt[i];
			pt[i] = pt[k];
			pt[k] = pt[0];
		}
	}
	printf("\n按书名排序后的结果为:");
	for ( i = 1; i <= n; i++)
	{
		printf("\n\n\n图书名称:%s",pt[i].name);
		printf("\n图书作者:%s",pt[i].author);
		printf("\n出版年份:%d,出版月份:%d,出版日期:%d", pt[i].time.year, pt[i].time.month, pt[i].time.day);
		printf("\n出版社:%s",pt[i].deriv);
		printf("\n借出数目:%d",pt[i].lend);
		printf("\n库存数目:%d",pt[i].reser);
	}
	getch();
}


4.10  在某次实弹训练中,班长将10个人围成一圈发子弹。

          首先,班长给第一个战士10颗,第二个战士2颗,第三个战士8颗,第四个战士22颗,第五个战士16颗,第六个战士4颗,第七个战士10颗,第八个战士6颗,第九个战士14颗,第十个战士20颗。

        然后按照如下方法对每个战士手中的子弹数进行调整。

        所有的战士检查自己手中的子弹数,若子弹数为奇数,则向班长再要一颗。然后每个战士再同时将自己手中的子弹的一半分给下一个战士(第10个战士将手中的子弹分一半给第一个战士)。

        问:需要多少次调整后,每个战士手中的子弹数都相等?都为多少颗?

        要求输出每轮调整后各战士手中的子弹数。结果的输出格式为:

        0  10  2  8  22  16  4  10  6 14  20    各战士手中的子弹数

        1  15  6  5  15  19 10  7   8 10  17    第1轮各战士手中的子弹数

        2。。。。。。。。。。。。。。    第2轮各战士手中的子弹数

        17 18 18 18 18 18 18 18 18 18 18 最后一轮各战士手中的子弹数(应相等)

       

       提示:为简单起见,在进行一轮分发时,可先判断每位战士手中的子弹数是否为偶数,若不是,则将这位战士手中的子弹数加1.

         然后,再考虑将每位战士手中的子弹同时分一半分下一位战士,这样每位战士手中的子弹数将是他原来的子弹数和他上一位手中的子弹数的平均数,如第2位战士的子弹数将是第1位战士的子弹数10和它本身的子弹数2的平均数6,第1位战士的子弹数将是第1位战士的子弹数和最后一位战士的子弹数20的平均数15,以此类推。


#include
void main()
{
	printf(" 在某次实弹训练中,班长将10个人围成一圈发子弹。首先,班长给第一个战士10颗,第二个战士2颗,第三个战士8颗,第四个战士22颗,\n第五个战士16颗,第六个战士4颗,第七个战士10颗,第八个战士6颗,第九个战士14颗,第十个战士20颗。\n然后按照如下方法对每个战士手中的子弹数进行调整。所有的战士检查自己手中的子弹数,若子弹数为奇数,则向班长再要一颗。\n然后每个战士再同时将自己手中的子弹的一半分给下一个战士(第10个战士将手中的子弹分一半给第一个战士)。\n问:需要多少次调整后,每个战士手中的子弹数都相等?都为多少颗?要求输出每轮调整后各战士手中的子弹数。\n结果的输出格式为:\n0  10  2  8  22  16  4  10  6 14  20    各战士手中的子弹数\n1  15  6  5  15  19 10  7   8 10  17    第1轮各战士手中的子弹数\n2。。。。。。。。。。。。。。    第2轮各战士手中的子弹数\n17 18 18 18 18 18 18 18 18 18 18 最后一轮各战士手中的子弹数(应相等)\n\n");
	int a[10] = { 10, 2, 8, 22, 16, 4, 10, 6, 14, 20 }, b[10] = { 0 }, i = 0, j = 0, temp = 0, k = 0;
	printf("%-4d", temp);
	for (i = 1; i <= 10; i++)
	{
		printf("%4d", a[i - 1]);
	}
	printf("\t\t各战士手中原始的子弹数.\n");
	while (k == 0)
	{
		for (j = 1; j < 10; j++)
		{
			if (a[0] != a[j])
			{
				k = 1;
			}
		}
		if (k == 1)
		{
			for (i = 1; i <= 10; i++)
			{
				if (a[i - 1] % 2 != 0)
				{
					a[i - 1] = a[i - 1] + 1;
				}
			}
			b[0] = a[0] / 2 + a[9] / 2;
			for (i = 1; i <= 9; i++)
			{
				b[i] = a[i - 1] / 2 + a[i] / 2;
			}
			temp = temp + 1;
			k = 0;
			for (j = 1; j < 10; j++)
			{
				if (a[0] != a[j])
				{
					k = 1;
				}
			}
			if (k==1)
			{
				printf("\n%-4d", temp);
				for (i = 1; i <= 10; i++)
				{
					printf("%4d", b[i - 1]);
				}
				printf("\t\t第%d轮各战士手中的子弹数.", temp);
				printf("\n");
				for (i = 1; i <= 10; i++)
				{
					a[i - 1] = b[i - 1];
				}
				k = 0;
			}
			else
			{
				printf("\n%-4d", temp);
				for (i = 1; i <= 10; i++)
				{
					printf("%4d", b[i - 1]);
				}
				printf("\t\t最后一轮各战士手中的子弹数.");
				break;
			}
		}
	}
	getch();
}


4.11  在保龄球比赛中,已知每次击倒的保龄球数,计算在一局比赛中一个人的得分,要求算出每一轮的得分和每一轮之后的累加得分。

          保龄球比赛一局共10轮,前9轮每一轮最多可以滚两次球;第10轮可以滚2次或3次球。每轮计分规则如下:

       (1)若一轮中第一个球全部击倒10个保龄球,称为Strike(好球),则这一轮的得分等于10加上下两次击倒保龄球的只数。

       (2)若一轮两个球全部击倒10只保龄球,称为Spare(成功),则这一轮的得分等于10加上下一次击倒保龄球的只数。

       (3)若一轮两个球一共击倒的保龄球只数少于10,称为Normal(平常),则这一轮的得分等于所击倒保龄球的总只数。

        要求输入20个数,表示一局中每一轮击倒的球数,程序每一轮中每两次输入的数之和不大于10,最后输入每一轮的得分和该局的总分。(和书中原题有些差别,原题有错误)

#include
void main()
{
	printf("在保龄球比赛中,已知每次击倒的保龄球数,计算在一局比赛中一个人的得分,要求算出每一轮的得分和每一轮之后的累加得分。\n保龄球比赛一局共10轮,前9轮每一轮最多可以滚两次球;第10轮可以滚2次或3次球。每轮计分规则如下:\n(1)若一轮中第一个球全部击倒10个保龄球,称为Strike(好球),则这一轮的得分等于10加上下两次击倒保龄球的只数。\n(2)若一轮两个球全部击倒10只保龄球,称为Spare(成功),则这一轮的得分等于10加上下一次击倒保龄球的只数。\n(3)若一轮两个球一共击倒的保龄球只数少于10,称为Normal(平常),则这一轮的得分等于所击倒保龄球的总只数。\n要求输入20个数,表示一局中每一轮击倒的球数,程序每一轮中每两次输入的数之和不大于10,最后输入每一轮的得分和该局的总分。");
	struct baolingqiu
	{
		int lun[2];
		int goal;
	};

	struct baolingqiu bao[11];
	int i, a = 0, k = 0, sumgoal = 0;

	for (i = 1; i < 10; i++)
	{
		printf("请输入第 %d 轮两次分别击倒的球数:",i);
		scanf("%d%d", &bao[i].lun[0], &bao[i].lun[1]);
	}

	printf("请输入第 10 轮两次分别击倒的球数:");
	scanf("%d%d", &bao[10].lun[0], &bao[10].lun[1]);

	if (bao[10].lun[0] + bao[10].lun[1] == 10)
	{
		printf("这轮成绩很好,可以扔第三次,请输入第三次的成绩:");
		scanf("%d", &a);
		k = 1;
	}
	else
	{
		printf("最后一轮很遗憾,没有第三次击球的机会。");
	}
	for (i = 1; i <= 9; i++)
	{
		if (bao[i].lun[0] == 10)
		{
			bao[i].goal = 10 + bao[i + 1].lun[0] + bao[i + 1].lun[1];
		}
		else if (bao[i].lun[0] + bao[i].lun[1] == 10)
		{
			bao[i].goal = 10 + bao[i + 1].lun[0];
		}
		else
		{
			bao[i].goal = bao[i].lun[0] + bao[i].lun[1];
		}
	}
	if (k == 1)
	{
		bao[10].goal = bao[10].lun[0] + bao[10].lun[1] + a;
	}
	else
	{
		bao[10].goal = bao[10].lun[0] + bao[10].lun[1];
	}
	for (i = 1; i <= 10; i++)
	{
		printf("\n第 %d 轮的得分为 %d", i, bao[i].goal);
		sumgoal = sumgoal + bao[i].goal;
	}
	printf("\n该局的总分为 %d", sumgoal);
	getch();
}


4.12  现将不超过2000的所有素数从小到大排成一行,第二行上的每个数等于他"右肩”上的数和“左肩”上的数之差,这样就可以得到两行数,如下表所示:

 

2

3

5

7

11

13

...

1997

1999

1

2

2

4

2

...

...

2


        试编程求解:在第二行中是否有多个连续的数之和等于1898?如有,将所有可能的组合输入。

        首先用筛选法求出2000以内的所有素数,再根据前面计算的结果求出第二行的所有数,存放在一个数组中。然后通过一个双重循环判断是否有多个连续的数之和等于1898这个问题。

        外层循环,对存储第二行数的下标进行枚举,依次从第二行的第一个数、第二个数开始进行处理,直到所有的数完成为止。

        内层循环中从当前元素进行累加,直到累加的和大于或等于1898为止。如果累加之和等于1898,则输出之,否则退出内层循环,继续进行外层循环的处理。

#include 
#include 
void main()
{
	printf("将不超过2000的所有素数从小到大排成一行,第二行上的每个数等于他“右肩”上的数和“左肩”上的数之差,是否有多个连续的数之和等于1898?\n\n");
	int i=0, j=0, m=0;
	int n = 2;
	int k = 0, sumyz = 0, a = 0;
	int ss[2000] = { 0 };
	ss[1] = 2;
	ss[2] = 3;
	int yzzc[2000] = { 0 };
	for (i = 4; i <= 2000; i++)
	{
		for (j = 2; j <= sqrt(i); j++)
		{
			if (i % j == 0)
			{
				k = k + 1;
				break;
			}
		}
		if (k == 0)
		{
			n = n + 1;
			ss[n] = i;
		}
		k = 0;
	}
	for (i = 1; i <= n - 1; i++)
	{
		yzzc[i] = ss[i + 1] - ss[i];
	}
	for (i = 1; i <= n - 1; i++)
	{
		for (j = i; j <= n - 1; j++)
		{
			sumyz = sumyz + yzzc[j];
			if (sumyz == 1898)
			{
				printf("满足连续可能组合的数之和为1898的排列如下:\n");
				for (m = i; m <= j; m++)
				{
					printf("%4d", yzzc[m]);
					a = a + 1;
					if (a % 5 == 0)
					{
						printf("\n");
					}
				}
				sumyz = 0;
			}
		}
	}
	getch();
}

4.13  产品质量调查,设有五种产品,分别为apple、pear、banana、orange、lemon,评定质量分为A、B、C三等,用键盘输入评定等级,输出每种产品为A的百分比。评定次数由键盘输入(N≥5)。

        提示:把产品名称定义为二维字符数组,通过循环和条件判定来进行处理。

#include
void main()
{
	printf("产品质量调查,设有五种产品,分别为apple、pear、banana、orange、lemon,评定质量分为A、B、C三等,\n用键盘输入评定等级,输出每种产品为A的百分比。评定次数由键盘输入(N≥5)。\n\n");
	float bap = 0, bpe = 0, bba = 0, bor = 0, ble = 0;
	float ap = 0, pe = 0, ba = 0, or = 0, le = 0;
	int i, n;
	struct foods
	{
		char apple[10];
		char pear[10];
		char banana[10];
		char orange[10];
		char lemon[10];
	};
	printf("请输入产品质量调查次数( >=5 ):");
	scanf("%d", &n);
	fflush(stdin);
	struct foods *food = (struct foods *)malloc(sizeof(struct foods)*(n + 1));
	for (i = 1; i <= n; i++)
	{
		printf("请输入第 %d 次产品评价\n", i);
	loop1: printf("请输入 apple 的评价:");
		scanf("%s", &food[i].apple);
		fflush(stdin);
		if (food[i].apple[0] - 'A' != 0 && food[i].apple[0] - 'B' != 0 && food[i].apple[0] - 'C' != 0)
		{
			printf("输入有错,需重新输入 apple 的评价");
			goto loop1;
		}
		if (food[i].apple[0] == 'A')
		{
			ap = ap + 1;
		}
	loop2: printf("请输入 pear 的评价:");
		scanf("%s", food[i].pear);
		fflush(stdin);
		if (food[i].pear[0] - 'A' != 0 && food[i].pear[0] - 'B' != 0 && food[i].pear[0] - 'C' != 0)
		{
			printf("输入有错,需重新输入 pear 的评价");
			goto loop2;
		}
		if (food[i].pear[0] == 'A')
		{
			pe = pe + 1;
		}
	loop3: printf("请输入 banana 的评价:");
		scanf("%s", food[i].banana);
		fflush(stdin);
		if (food[i].banana[0] - 'A' != 0 && food[i].banana[0] - 'B' != 0 && food[i].banana[0] - 'C' != 0)
		{
			printf("输入有错,需重新输入 banana 的评价");
			goto loop3;
		}
		if (food[i].banana[0] == 'A')
		{
			ba = ba + 1;
		}
	loop4: printf("请输入 orange 的评价:");
		scanf("%s", food[i].orange);
		fflush(stdin);
		if (food[i].orange[0] - 'A' != 0 && food[i].orange[0] - 'B' != 0 && food[i].orange[0] - 'C' != 0)
		{
			printf("输入有错,需重新输入 orange 的评价");
			goto loop4;
		}
		if (food[i].orange[0] == 'A')
		{
			or = or + 1;
		}
	loop5: printf("请输入 lemon 的评价:");
		scanf("%s", food[i].lemon);
		fflush(stdin);
		if (food[i].lemon[0] - 'A' != 0 && food[i].lemon[0] - 'B' != 0 && food[i].lemon[0] - 'C' != 0)
		{
			printf("输入有错,需重新输入 lemon 的评价");
			goto loop5;
		}
		if (food[i].lemon[0] == 'A')
		{
			le = le + 1;
		}
	}
	bap = ap / n;
	bpe = pe / n;
	bba = ba / n;
	bor = or / n;
	ble = le / n;
	printf("\n产品中 apple 评定等级为 A 的百分比为:%f\n", bap);
	printf("\n产品中 pear 评定等级为 A 的百分比为:%f\n", bpe);
	printf("\n产品中 banana 评定等级为 A 的百分比为:%f\n", bba);
	printf("\n产品中 orange 评定等级为 A 的百分比为:%f\n", bor);
	printf("\n产品中 lemon 评定等级为 A 的百分比为:%f\n", ble);
	getch();
}



                                         业精于勤荒于嬉,行成于思毁于随。撸代码的你,好好加油吧!





你可能感兴趣的:(余勤课后习题答案)