头歌C语言实验 辅助练习9:使用数组

第1关:选秀评分

问题描述
现举办一个选秀活动,有十位评委为选手打分,每位评委按照十分制独立给选手打分。选手的最后得分的计算规则是:去掉一个最高分,去掉一个最低分,然后计算剩下八个分数的平均分。请用数组编写一个程序,请用户输入十位评委给出的分数,计算并输出该选手的最终得分,输出结果保留2位小数。

输入
用空格分开的10个浮点数代表10个评委的打分。

输出
参照示例格式输出该选手的最终得分,所有浮点数保留两位小数。
输出内容中所有标点符号均为中文的标点符号。

输入示例
9.6 9.6 9.9 9.7 9.8 9.4 9.6 9.7 9.9 9.5

输出示例
去掉一个最高分9.90分,去掉一个最低分9.40分,该选手最终得分9.67分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include<stdio.h>
int main(){
int i;
double score[10];
double max,min,sum,avg;
scanf("%lf",&score[0]);
sum=max=min=score[0];
for(i=1;i<10;i++){
scanf("%lf",&score[i]);
if(score[i]>max)
max=score[i];
if(score[i]<min)
min=score[i];
sum+=score[i];
}
sum=sum-max-min;
avg=sum/8;
printf("去掉一个最高分%.2lf分,去掉一个最低分%.2lf分,该选手最终得分%.2lf分。",max,min,avg);
return 0;
}

第2关:杨辉三角形

问题描述
杨辉三角形的实质是二项式(a+b)的n次方展开后各项的系数排成的三角形,它的特点是在这个三角形中,每一行第一个数和最后一个数都是1,从第三行起,中间的每一个数是上一行里相邻两个数之和。例如,以下是杨辉三角形的前6行:

1
2
3
4
5
6
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

根据用户输入正整数n(n≤20),请使用二维数组编程计算并输出杨辉三角形的前n行。

输入
一个正整数n(n≤20),表示杨辉三角形的行数。

输出
杨辉三角形的前n行,每行中两个整数之间用一个空格分开。
注意每行中的最后一个整数后面不要有多余的空格。

输入示例
6

输出示例

1
2
3
4
5
6
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
int main(){
int n,i,j;
int **arr;
scanf("%d",&n);
arr=(int**)malloc(n*sizeof(int*));
for(i=0;i<n;i++){
arr[i]=(int*)malloc(n*sizeof(int));
}
for(i=0;i<n;i++){
arr[i][0]=1;
arr[i][i]=1;
for(j=1;j<i;j++){
arr[i][j]=arr[i-1][j-1]+arr[i-1][j];
}
}
for(i=0;i<n;i++){
for(j=0;j<=i;j++){
printf ("%d",arr[i][j]);
if(j!=i)
printf(" ");
}
printf("\n");
}
return 0;
}

第3关:掷骰子

问题描述
掷骰子是我们经常玩的一种简单的游戏,一个骰子有6个面,分别表示1,2,3,4,5,6。从概率学的角度看来,在不作弊的前提下,每次投掷骰子后出现的点数是完全随机的,各个面的出现概率应该是相等的。
请编写程序模拟骰子的6000次投掷过程,统计并输出骰子的6个面各自出现的次数和概率。

提示
使用一个数组来统计骰子6个面各自出现的次数;
投掷一次骰子出现哪个面是随机的,因此可以使用随机函数rand()产生随机数模拟骰子投掷后出现的点数;
使用运行程序时用户输入的非负整数n作为产生随机数序列的种子,具体使用方法可以参考教材上P117的示例程序。
输入
一个非负整数n,用来作为产生随机数序列的种子。

输出
输出包括6行,分别按顺序对应于骰子1、2、3、4、5、6六个面。
每行参照示例输出在6000次投掷过程中,对应点数的出现次数和概率(保留2位小数)。
输出内容中所有标点符号均为中文的标点符号。

特别提示
因为在不同机型上产生的随机数序列可能不尽相同,因此运行测试结果可能和以下示例结果有所区别,示例仅供参考,但骰子各个面的出现次数及出现概率应该基本相同。

输入示例
0

输出示例
1共出现了1080次,出现概率为0.18。
2共出现了958次,出现概率为0.16。
3共出现了965次,出现概率为0.16。
4共出现了1002次,出现概率为0.17。
5共出现了999次,出现概率为0.17。
6共出现了996次,出现概率为0.17。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <stdlib.h>
int main(){
int n,i,magic;
int num[6]={0};
scanf("%d",&n);
srand(n);
for(i=0;i<6000;i++){
magic=rand()%6+1;
switch(magic){
case 1:
num[0]++;
break;
case 2:
num[1]++;
break;
case 3:
num[2]++;
break;
case 4:
num[3]++;
break;
case 5:
num[4]++;
break;
case 6:
num[5]++;
break;
default:
break;
}
}
for(i=0;i<6;i++){
printf("%d共出现了%d次,出现概率为%.2lf。\n",i+1,num[i],(double)num[i]/6000);
}
return 0;
}

第4关:肿瘤检测

问题描述
一张CT扫描的灰度图像可以用一个N×N(0<N<100)的矩阵描述,矩阵上的每个点对应一个灰度值(整数),其取值范围是0-255。
假设给定的图像中有且只有一个肿瘤。在图上监测肿瘤的方法如下:
如果某个点对应的灰度值小于等于50,则这个点在肿瘤上,否则不在肿瘤上。
把在肿瘤上的点的数目加起来,就得到了肿瘤在图上的面积。
任何在肿瘤上的点,如果它是图像的边界或者它的上下左右四个相邻点中至少有一个是非肿瘤上的点,则该点称为肿瘤的边界点。肿瘤的边界点的个数称为肿瘤的周长。
现在给定一张CT扫描的灰度图像,要求计算其中的肿瘤的面积和周长。

输入
输入第一行包含一个正整数N(0<N<100),表示图像的大小;接下来N行,每行包含图像的一行。图像的一行用N个整数表示(所有整数大于等于0,小于等于255),两个整数之间用一个空格隔开。

输出
输出只有一行,该行包含两个正整数,分别为给定图像中肿瘤的面积和周长,用一个空格分开。

输入示例

1
2
3
4
5
6
7
6
99 99 99 99 99 99
99 99 99 50 99 99
99 99 49 49 50 51
99 50 20 25 52 99
40 50 99 99 99 99
99 99 99 99 99 99

输出示例
9 8

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include<stdio.h>
#include<stdlib.h>
int main(){
int N,i,j,s=0,c=0;
int **arr;
scanf("%d",&N);
arr=(int**)malloc(N*sizeof(int*));
for(i=0;i<N;i++){
arr[i]=(int*)malloc(N*sizeof(int));
}
for(i=0;i<N;i++){
for(j=0;j<N;j++){
scanf("%d",&arr[i][j]);
}
}
for(i=0;i<N;i++){
for(j=0;j<N;j++){
if(arr[i][j]<=50){
s++;
if(i==0||i==N-1||j==0||j==N-1)
c++;
else if(arr[i-1][j]>50||arr[i+1][j]>50||arr[i][j-1]>50||arr[i][j+1]>50)
c++;
}
}
}
printf("%d %d",s,c);
return 0;
}

第5关:两倍

问题描述
给定2到15个不同的正整数,你的任务是计算这些数里面有多少个数对满足:数对中一个数是另一个数的两倍。
比如给定1 4 3 2 9 7 18 22,得到的答案是3,因为2是1的两倍,4是2个两倍,18是9的两倍。

输入
输入包括多组测试数据。每组数据包括一行,给出2到15个两两不同且小于100的正整数。每一行最后一个数是0,表示这一行的结束,这个数不属于那2到15个给定的正整数。输入的最后一行只包括一个整数-1,这行表示输入数据的结束,不用进行处理。

输出
对每组输入数据单独输出一行,表示有多少个数对满足其中一个数是另一个数的两倍。

提示
根据输入数据的说明,把每行末尾的0算上,每行最多可能输入16个整数。

输入示例

1
2
3
4
1 4 3 2 9 7 18 22 0
2 4 8 10 0
7 5 11 13 1 3 0
-1

输出示例
3
2
0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include<stdio.h>

int main(){
int i=0,count=0;
int j,t,k;
int num[16];
while(1){
scanf("%d",&t);
if(t==-1)
break;
if(t!=0&&t!=-1){
num[i++]=t;
}
if(getchar()=='\n'||t==0){
for(j=0;j<i;j++){
for(k=j+1;k<i;k++){
if((num[k]/num[j]==2&&num[k]%num[j]==0)||(num[j]/num[k]==2&&num[j]%num[k]==0))
count++;
}
}
printf("%d\n",count);
count=0;
i=0;
}
}
return 0;
}

第6关:成绩排序

问题描述
张老师的班上共有n名学生(最多不超过60人)。期末考试结束后,经过辛苦的阅卷,全班同学的考试成绩都出来了。张老师想要对全班同学的成绩按照从高到低的顺序进行排序。但是张老师实在没有精神再连续工作下去了,聪明的你能够帮助张老师吗?

输入
输入包括两行:
第一行是一个正整数n,表示张老师班上的总人数。
第二行共包括n个浮点数,每个浮点数表示一位同学的期末考试成绩。

输出
输出共有n行,按照成绩从高到低的顺序每行输出一个成绩。
每行中先输出序号(从1开始,占2个字符宽度),然后是一个小数点(.)和一个空格,最后是期末考试成绩,保留2位小数。

输入示例
12
85.6 83.47 45.8 96.3 100 37.4 68.9 96.6 88 84.6 94.7 78.8

输出示例

  1. 100.00
  2. 96.60
  3. 96.30
  4. 94.70
  5. 88.00
  6. 85.60
  7. 84.60
  8. 83.47
  9. 78.80
  10. 68.90
  11. 45.80
  12. 37.40
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include<stdio.h>
#include<stdlib.h>
void Compare(double* num,int n){
int i,j;
double t;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(num[j]<num[j+1]){
t=num[j];
num[j]=num[j+1];
num[j+1]=t;
}
}
}
}
int main(){
int i,n;
double *score;
double max=0,min=100;
scanf("%d",&n);
score = (double *)malloc(n*sizeof(double));
for(i=0;i<n;i++){
scanf("%lf",&score[i]);
}
Compare(score,n);
for(i=0;i<n;i++){
printf("%2d. %.2lf\n",i+1,score[i]);
}
return 0;
}