C语言提高-第18讲: 一维数组应用二三例(发奖金)

xiaoxiao2021-02-28  25

任务和代码(一):

/* *All rights reserved *文件名称:main.c *作者: Osseyda 完成日期:2017.10.17 *版本号:v2. *问题描述:过年了,村里要庆祝一下。村长对村里的128个村民说:做一个游戏,让每个人把出生年+月+日得到一个数。例如:1995年11月8日=1995+11+8=2014。然后把这个数报上来。村里有一笔钱要作为游戏的奖金,数额为M元(在程序中可以用常量固定为一个数)。如果有人报上来的数字与M相同,就把这笔钱发给这些人。如果只有一个人得奖,奖金都归这个人。如果有多于一个人得奖,则他们平分这笔钱。现在让我们来写一段程序算算都有哪些人得到了奖金?得到多少?请写出这个程序。 */ #include <stdio.h> int main(){ int a[5],lucy,i,j,count=0,index[5],bonus; double aver; printf("幸运数是:"); scanf("%d",&lucy); printf("奖金:"); scanf("%d",&bonus); printf("\n"); for(i=0,j=0;i<5;i++){ scanf("%d",&a[i]); if(lucy==a[i]){ count++; index[j++]=i; } } aver=(double)bonus/count; printf("共有 %d 人得到奖金 %.2f 元\n",count,aver); printf("他们分别是:\n"); for(i=0;i<j;i++) printf("%d ",index[i]); return 0; }

运行结果:

任务和代码(二):

/* *问题描述:有村民提出村长在幸运数字上做手脚,不公平。修改后的规则是:每人写一个1000以内的数字,谁写的数字与平均值最接近,M元的奖金就由谁拿,有多人与平均值差值相同,则均分。例如,参加的村民有5个人,报的数字分别为98、7、50、980、1,平均值为227(平均值也取成整数就行了),与98最接近,编号为0的村民得奖。这个游戏实际上有很强的政治学背景,一种策略是串通,大家都报一样的数,平分奖金;在每个人都想争取最大利益的前提下,各人报的数字又对结果都有影响,这里面包含一系列非常有意思的研究课题。 *提示:输入数据后,用一次循环求和,进而求出平均值;再一次循环,求出最小的差值;再一次循环,将差值最小的村民的编号放入幸运数组(因为可能不止一位,所以需要这个数组)。 */ #include <stdio.h> #define bonus 2014 #define num 8 int main(){ int a[100],b[100],index[100],i,j,k,sum=0,count=0,min; double mean,aver; for(i=0;i<num;i++){ scanf("%d",&a[i]); sum+=a[i]; } mean=(double)sum/num; //找出与平均值最接近的报数与其对应的学号 for(i=0,j=0;i<num;i++){ //由a[i]的元素与mean的正差值得到b[i] if(a[i]>=mean) b[j++]=a[i]-mean; else b[j++]=mean-a[i]; } min=b[0]; for(i=0;i<j;i++){ //找到b[i]中最小的元素,即最小差值的报数 if(min>b[i]) min=b[i]; } for(i=0,k=0;i<j;i++){ //计算min的个数及其对应的序号 if(b[i]==min){ count++; index[k++]=i; } } aver=(double)bonus/count; printf("共有 %d 人得到奖金 %.2f 元\n",count,aver); printf("他们分别是:\n"); for(i=0;i<k;i++) printf("%d ",index[i]); return 0; } 运行结果:

将任务和代码(二)做改进:将找正差值及其最小值放入一个循环中

#include <stdio.h> #define BONUS 2014 #define NUM 8 int main(){ int a[NUM],b[NUM],index[NUM],i,j,k; double aver,mean,min=9999,sum=0; for(i=0;i<NUM;i++){ scanf("%d",&a[i]); sum+=a[i]; } mean=sum/NUM; //找出与平均值最接近的报数与其对应的学号 for(i=0,j=0;i<NUM;i++){ //由a[i]的元素与mean的正差值得到b[j] if(a[i]>=mean) b[j++]=a[i]-mean; else b[j++]=mean-a[i]; if(min>b[j-1]) //找出min min=b[j-1]; } for(i=0,k=0;i<NUM;i++){ //计算min的个数及其对应的序号 if(b[i]==min) index[k++]=i; } aver=(double)BONUS/k; printf("共有 %d 人得到奖金 %.2f 元\n",k,aver); printf("他们分别是:\n"); for(i=0;i<k;i++) printf("%d ",index[i]); return 0; }

由于正差值并没必要保存在数组中,因此可以直接把最小正差值设为一个变量:

#include <stdio.h> #define BONUS 2014 #define NUM 8 int main(){ int a[NUM],index[NUM],i,j; double aver,mean,min=9999,minu,sum=0; for(i=0;i<NUM;i++){ scanf("%d",&a[i]); sum+=a[i]; } mean=sum/NUM; //找出与平均值最接近的报数与其对应的学号 for(i=0;i<NUM;i++){ //由a[i]的元素与mean的正差值得到b[j] if(a[i]>=mean) minu=a[i]-mean; else minu=mean-a[i]; if(min>minu) //找出min min=minu; } for(i=0,j=0;i<NUM;i++){ //计算min的个数及其对应的序号 if(a[i]-mean==min||mean-a[i]==min)) index[j++]=i; } aver=(double)BONUS/j; printf("共有 %d 人得到奖金 %.2f 元\n",j,aver); printf("他们分别是:\n"); for(i=0;i<j;i++) printf("%d ",index[i]); return 0; }

知识点总结:

       对原生数组中的数据进行折腾,得到想要的数据或者符合条件的新数组并输出

心得:

       好好理解题目,再想出合适的算法,并用代码描述,最后进行优化。正确的解题都应该是这样的步骤吧~

      尤其注意变量类型的定义和使用,有可能进行一次强制类型转换后结果即出错,如:

      minu=a[i]-mean; 如果minu是int型,只要a[i]-mean几乎不会等于min

      数值计算中尽量避免强制类型转换

转载请注明原文地址: https://www.6miu.com/read-1450186.html

最新回复(0)