哈工大C语言程序设计精髓MOOC 第十二周编程题

第十二周 海陆空齐上阵:又来了一堆数据

练兵区——编程题——不计入总分

1大奖赛现场统分(4分)

题目内容:
已知某大奖赛有n个选手参赛,m(m>2)个评委为参赛选手评分(最高10分,最低0分)。统分规则为:在每个选手的m个得分中,去掉一个最高分和一个最低分后,取平均分作为该选手的最后得分。要求编程实现:
(1)根据n个选手的最后得分,从高到低输出选手的得分名次表,以确定获奖名单;
(2)根据各选手的最后得分与各评委给该选手所评分数的差距,对每个评委评分的准确性和评分水准给出一个定量的评价,从高到低输出各评委得分的名次表。
提示:首先设计如下5个数组:
(1)sh[i],存放第i个选手的编号;
(2)sf[i],存放第i个选手的最后得分,即去掉一个最高分和一个最低分以后的平均分;
(3)ph[j],存放第j个评委的编号;
(4)f[i][j],存放第j个评委给第i个选手的评分;
(5)pf[j],存放代表第j个评委评分水准的得分。

#include<stdio.h>
#include<math.h>
#define N 10

void inputData(int n, int m, int *sh, int *ph, float *f, float *sf, float *pf);
void findMinMax(int n, float arr[], int *min, int *max);
void sortData(int n, int m, int *sh, int *ph, float *sf, float *pf);
void sortAthletes(int n, int *sh, float *sf);
void sortJudge(int m, int *ph, float *pf);

int main(){
	int n, m, sh[N], ph[N];
	float sf[N], f[N][N], pf[N];
	printf("How many Athletes?\n");
	scanf("%d", &n);
	printf("How many judges?\n");
	scanf("%d", &m);
	
	inputData(n, m, sh, ph, *f, sf, pf);
	
	sortData(n, m, sh, ph, sf, pf);
	printf("Over!Thank you!\n");
	return 0;
}

void inputData(int n, int m, int *sh, int *ph, float *f, float *sf, float *pf){
	printf("Scores of Athletes:\n");
	
	for(int i = 0; i < m; i++){
		*(ph + i) = i + 1; 
	}
	int min, max;
	for(int i = 0; i < n; i++){
		printf("Athlete %d is playing.\n", i + 1);
		printf("Please enter his number code:\n");
		scanf("%d", (sh + i));
		*(sf + i) = 0;
		for(int j = 0; j < m; j++){
			printf("Judge %d gives score:\n", j + 1);
			scanf("%f", (f + i * N + j));
			*(sf + i) += *(f + i * N + j);
		} 
		// findMinMax 
		findMinMax(m, f + i * N, &min, &max);
		*(sf + i) = *(sf + i) - *(f + i * N + min) - *(f + i * N + max);
		*(sf + i) = *(sf + i) / (m - 2);
		printf("Delete a maximum score:%.1f\n", *(f + i * N + max));
		printf("Delete a minimum score:%.1f\n", *(f + i * N + min));
		printf("The final score of Athlete %d is %.3f\n", *(sh +i), *(sf + i));
	}
	
	// calculate judge's scores
	float sum;
	for(int i = 0; i < m; i++){
		sum = 0;
		for(int j = 0; j < n; j++){
			sum = sum + pow(*(f + j * N + i) - *(sf + j) , 2);
		}
		*(pf + i) = 10 - sqrt( sum / n );
	}
}

void findMinMax(int n, float arr[], int *min, int *max){
	*min =  0;
	*max = 0;
	for(int i = 1; i < n; i++){
		if(arr[*min] > arr[i]){
			*min = i;
		}
		if(arr[*max] < arr[i]){
			*max = i;
		}
	}
}

void sortData(int n, int m, int *sh, int *ph, float *sf, float *pf){
	sortAthletes(n, sh, sf);
	sortJudge(m, ph, pf);
	printf("Order of Athletes:\n");
	printf("order\tfinal score\tnumber code\n");
	for(int i = 0; i < n; i++){
		printf("%5d\t%11.3f\t%6d\n", i + 1, *(sf + i), *(sh + i));
	}
	
	printf("Order of judges:\n");
	printf("order\tfinal score\tnumber code\n");
	for(int i = 0; i < m; i++){
		printf("%5d\t%11.3f\t%6d\n", i + 1, *(pf + i), *(ph + i));
	}
}

void sortAthletes(int n, int *sh, float *sf){
	int maxP, tempH; 
	float tempF;
	for(int i = 0; i < n;i++){
		maxP = i;
		for(int j = i + 1; j < n; j++){
			if(*(sf + maxP) < *(sf + j)){
				maxP = j;
			}
		}
		// swap
		if(maxP != i){
			tempH = *(sh + maxP);
			tempF = *(sf + maxP);
			*(sh + maxP) = *(sh + i);
			*(sf + maxP) = *(sf + i);
			*(sh + i) = tempH;
			*(sf + i) = tempF; 
		}
	}
}

void sortJudge(int m, int *ph, float *pf){
	int minP, tempH;
	float tempF;
	for(int i = 0; i < m;i++){
		minP = i;
		for(int j = i + 1; j < m; j++){
			if(*(pf + minP) < *(pf + j)){
				minP = j;
			}
		}
		// swap
		if(minP != i){
			tempH = *(ph + minP);
			tempF = *(pf + minP);
			*(ph + minP) = *(ph + i);
			*(pf + minP) = *(pf + i);
			*(ph + i) = tempH;
			*(pf + i) = tempF; 
		}
	}
}

3单词接龙(4分)

题目内容:
阿泰和女友小菲用英语短信玩单词接龙游戏。一人先写一个英文单词,然后另一个人回复一个英文单词,要求回复单词的开头有若干个字母和上一个人所写单词的结尾若干个字母相同,重合部分的长度不限。(如阿泰输入happy,小菲可以回复python,重合部分为py。)现在,小菲刚刚回复了阿泰一个单词,阿泰想知道这个单词与自己发过去的单词的重合部分是什么。他们两人都是喜欢写长单词的英语大神,阿泰觉得用肉眼找重合部分实在是太难了,所以请你编写程序来帮他找出重合部分。

#include<stdio.h>
#define N 100 

int findSimilarity(char *str1, char *str2, char *res);
void storeRes(char *str, char *res);

int main() {
	char str1[N], str2[N], res[N];
	scanf("%s%s", str1, str2);
	
	int flag = findSimilarity(str1, str2, res);
	if(flag == 0){
		printf("%s\n", res);
	}
	
	return 0;
}

int findSimilarity(char *str1, char *str2, char *res){
	char *temp1, *temp2;
	while(*str1){
		 temp1 = str1;
		 temp2 = str2;
		 while(*temp1 == *temp2){
		 	temp1++;
		 	temp2++;
		 }
		 if(*temp1 == '\0'){
		 	// find
		 	storeRes(str1, res);
		 	return 0;
		 }
		 str1++;
	}
	return -1;
}

void storeRes(char *str, char *res){
	while(*str){
		*res = *str;
		str++;
		res++;
	}
	*res = '\0';
}

4分数比较(4分)

题目内容:
比较两个分数的大小。人工方式下比较分数大小最常见的方法是:进行分数的通分后比较分子的大小。可以编程模拟手工解决。
具体要求为首先输出(“Input two FENSHU:\n”),然后输入两个分数分子分母的值,格式为("%d/%d,%d/%d"),判断完成后输出("%d/%d<%d/%d\n")或("%d/%d>%d/%d\n")或("%d/%d=%d/%d\n");

#include<stdio.h>

typedef struct number {
	int molecule;
	int denominator;
}NUMBER;

int compareNUMBER(const NUMBER *num1, const NUMBER *num2);
int Gcd(int a, int b); 

int main(){
	NUMBER number1, number2;
	printf("Input two FENSHU:\n");
	scanf("%d/%d,%d/%d", &number1.molecule, &number1.denominator, &number2.molecule, &number2.denominator);
	
	int res = compareNUMBER(&number1, &number2);
	if(res == 1){
		printf("%d/%d>%d/%d\n", number1.molecule, number1.denominator, number2.molecule, number2.denominator);
	}else if(res == -1){
		printf("%d/%d<%d/%d\n", number1.molecule, number1.denominator, number2.molecule, number2.denominator);
	}else {
		printf("%d/%d=%d/%d\n", number1.molecule, number1.denominator, number2.molecule, number2.denominator);
	}
	return 0;
}

int compareNUMBER(const NUMBER *num1, const NUMBER *num2){
	// 先求分母的公约数
	int gcdRes = Gcd(num1->denominator, num2->denominator);
	int molecule1 = num1->molecule * num2->denominator / gcdRes;
	int molecule2 = num2->molecule * num1->denominator / gcdRes;
	
	if(molecule1 > molecule2){
		return 1;
	}else if(molecule1 < molecule2){
		return -1;
	}else{
		return 0;
	}
}

int Gcd(int a, int b){
	if(a == b) return a;
	
	if(a > b){
		Gcd(a-b, b);
	}
	else{
		Gcd(a, b -a);
	}
}

5百万富翁的换钱计划(4分)

题目内容:
有一天,一位百万富翁遇到一个陌生人,陌生人找他谈一个换钱的计划,陌生人对百万富翁说:“我每天给你10万元,而你第一天只需给我1分钱,第二天我仍给你10万元,你给我2分钱,第三天我仍给你10万元,你给我4分钱……。你每天给我的钱是前一天的两倍,直到满一个月(30天)为止”,百万富翁很高兴,欣然接受了这个契约。请编程计算在这一个月中陌生人总计给百万富翁多少钱,百万富翁总计给陌生人多少钱。程序中浮点数的数据类型均为double。

#include <stdio.h>
#include <math.h>
int main()
{
	int i, n=30;
	double sum1=0, sum2=0;
	for(i=1;i<=n;i++)
	{
		sum1 = sum1 + 100000;
		sum2 = sum2 + pow(2,i-1)*0.01;
	}
	printf("to Stranger: %.2f yuan\n", sum2);
	printf("to Richman: %.2f yuan\n", sum1);
	return 0;
}

6用计数控制的循环实现正数累加求和(4分)

题目内容:
输入一些整数,编程计算并输出其中所有正数的和,输入负数时不累加,继续输入下一个数。输入零时,表示输入数据结束。要求最后统计出累加的项数。

#include<stdio.h>

int main(){
	int input, count = 0, sum = 0;
	do {
		printf( "Input a number:\n");
		scanf("%d", &input);
		if(input > 0){
			count++;
			sum += input;
		}
	}while(input != 0);
	printf("sum=%d,count=%d\n", sum, count);
	return 0;
}

7平方根表(4分)

题目内容:
输出100(n2<=100)以内整数的平方根表,n的值要求从键盘输入,并且满足n2<=100 (即n的平方值在100以内)。

#include<stdio.h>
#include<math.h>

int main()
{
    int n;
    printf("Input n(n<=10):\n");
    scanf("%d", &n);
    if(n <= 10)
    {
        for (int i = 0; i < n; ++i)
        {
            printf("%7d", i);
        }
        printf("\n");
        for (int i = 0; i < n; ++i)
        {
            printf("%d", i);
            for (int j = 0; j < n; ++j)
            {
                printf("%7.3f", sqrt(i * 10 + j));
            }
            printf("\n");
        }
    }
    return 0;
}

8最大公约数(4分)

题目内容:
按照如下函数原型编写子函数计算正整数a和b的所有公约数。第一次调用,返回最大公约数。以后只要再使用相同参数调用,每次返回下一个小一些的公约数。无公约数时,函数CommonFactors()返回-1,主函数中不输出任何信息。
函数原型: int CommonFactors(int a, int b)

int CommonFactors(int a, int b);
 
int n=1;
int main()
{
    int a, b, result, i;
    printf("Input a and b:\n");
    scanf("%d,%d", &a, &b);
    result = CommonFactors(a, b);
    if(a>0 && b>0)
    {
        for(i=1;result != -1;i++)
        {
            n++;
            printf("Common factor %d is %d\n", i, result);
            result = CommonFactors(a, b);
        }
    }
    return 0;
}
 
int CommonFactors(int a, int b)
{
    int i, count = 0;
    for (i = a; i >= 1; i--)
    {
        if (a % i == 0 && b % i == 0)
        {
            count++;
        }
        if (n == count)
            return i;
    }
    return -1;
}

9 23根火柴游戏(4分)

题目内容:

请编写一个简单的23 根火柴游戏程序,实现人跟计算机玩这个游戏的程序。为了方便程序自动评测,假设计算机移动的火柴数不是随机的,而是将剩余的火柴根数对3求余后再加1来作为计算机每次取走的火柴数。如果剩余的火柴数小于3,则将剩余的火柴数减1作为计算机移走的火柴数。但是计算机不可以不取,剩下的火柴数为1时,必须取走1根火柴。假设游戏规则如下:
1)游戏者开始拥有23根火柴棒;
2)每个游戏者轮流移走1 根、2 根或3 根火柴;
3)谁取走最后一根火柴为失败者。

#include<stdio.h>

void playerMove(int *number);
void computerMove(int *number);

int main() { 
	printf("Game start!\n");
	printf( "Note: the maximum number is 3\n");
	int count = 23;
	
	while(count > 0){
		playerMove(&count);
		computerMove(&count);
	}
	
	return 0;
}


void playerMove(int *number){
	int n, flag = 0;
	do {
		printf("Please enter the number of matches you are moving:\n");
		scanf("%d", &n);
		if(n > 3||n < 0){
			printf("The number you entered is wrong,please re-enter!\n");
			flag = 0;
		}else {
			flag = 1;
		}
	}while(flag == 0);
	
	printf("The number of matches you are moving is:%d\n", n);
	*number -= n;
	printf("The number of matches left is:%d\n", *number);
	if(*number == 0){
		printf("I'm sorry. You lost!\n");
	}
	
}
void computerMove(int *number){
	int n;
	if(*number < 3){
		n = 1;
	}else if(*number >= 3){
		n = *number % 3 + 1;
	}
	
	printf("The number of matches that have been moved by the computer is:%d\n", n);
	*number -= n;
	printf("The number of matches left is:%d\n", *number);
	if(*number == 0){
		printf("Congratulations!You won!\n");
	}
}

第12周编程题在线测试

1计算时间差V2.0(4分)

题目内容:

用结构体定义时钟类型,编程从键盘任意输入两个时间(例如4时55分和1时25分),计算并输出这两个时间之间的间隔。要求不输出时间差的负号。结构体类型定义如下:

typedef struct clock
{
    int hour;
    int minute;
    int second;
} CLOCK;

函数原型: CLOCK CalculateTime(CLOCK t1, CLOCK t2);
函数功能:计算并返回两个时间t1和t2之间的差

#include<stdio.h>
#include<math.h>

typedef struct clock {
	int hour;
	int minute;
	int second;
} CLOCK;

CLOCK CalculateTime(CLOCK t1, CLOCK t2);

int main() {
	CLOCK clk1, clk2;
	printf( "Input time one:(hour,minute):");
	scanf("%d,%d", &clk1.hour, &clk1.minute);
	printf( "Input time two: (hour,minute):");
	scanf("%d,%d", &clk2.hour, &clk2.minute);

	CLOCK res = CalculateTime(clk1, clk2);
	printf("%dhour,%dminute\n", res.hour, res.minute);
	return 0;
}

CLOCK CalculateTime(CLOCK t1, CLOCK t2) {
	int total1 = t1.hour * 60 + t1.minute;
	int total2 = t2.hour * 60 + t2.minute;
	int distance = abs(total1 - total2);
	
	CLOCK res;
	res.hour = distance / 60;
	res.minute = distance % 60;
	
	return res;
}

2奖学金发放(4分)

题目内容:
某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,每项奖学金获取的条件分别如下:

  1. 院士奖学金:期末平均成绩高于80分(>80),并且在本学期内发表1篇或1篇以上论文的学生每人均可获得8000元;
  2. 五四奖学金:期末平均成绩高于85分(>85),并且班级评议成绩高于80分(>80)的学生每人均可获得4000元;
  3. 成绩优秀奖:期末平均成绩高于90分(>90)的学生每人均可获得2000元;
  4. 西部奖学金:期末平均成绩高于85分(>85)的西部省份学生每人均可获得1000元;
  5. 班级贡献奖:班级评议成绩高于80分(>80)的学生干部每人均可获得850元;
    只要符合上述条件就可获得相应的奖项,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。例如姚明的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。
    现在给出若干学生的相关数据(假设总有同学能满足获得奖学金的条件),请编程计算哪些同学获得的奖金总数最高。
#include<stdio.h>
#define N 30

typedef struct winners {
    char name[20];
    int finalScore;
    int classScore;
    char work;
    char west;
    int paper;
    int scholarship;
} WIN;

void Addup(WIN stu[], int n);
int FindMax(WIN student[], int n);
int getScholarship(WIN *student);

int main() {
	int n;
	printf("Input n:");
	scanf("%d", &n);
	
	WIN stu[N];
	Addup(stu, n);
	int maxP = FindMax(stu, n);
	
	printf("%s get the highest scholarship %d\n", (stu + maxP)->name, (stu + maxP)->scholarship);
	return 0;
}

void Addup(WIN stu[], int n){
	for(int i = 0; i < n; i++){
		printf("Input name:");
		scanf("%s", &(stu + i)->name);
		printf("Input final score:");
		scanf("%d", &(stu + i)->finalScore);
		
		printf("Input class score:");
		scanf("%d", &(stu + i)->classScore);
		printf("Class cadre or not?(Y/N):");
		scanf(" %c", &(stu + i)->work);
		printf("Students from the West or not?(Y/N):");
		scanf(" %c", &(stu + i)->west); 
		printf("Input the number of published papers:");
		scanf("%d", &(stu + i)->paper);
		
		(stu + i)->scholarship = getScholarship(stu + i);
		
		printf("name:%s,scholarship:%d\n", (stu + i)->name, (stu + i)->scholarship);
	}
}

int getScholarship(WIN *student){
	int count = 0;
	if(student->finalScore > 80&&student->paper > 0) count += 8000;
	
	if(student->finalScore > 85&&student->classScore > 80) count += 4000;
	
	if(student->finalScore > 90) count += 2000;
	
	if(student->west == 'Y'&&student->finalScore > 85) count += 1000;
	
	if(student->work == 'Y'&&student->classScore > 80) count += 850;
	return count;
}

int FindMax(WIN student[], int n){
	int maxP = 0;
	for(int i = 1; i < n; i++){
		if((student + i)->scholarship > (student + maxP)->scholarship){
			maxP = i;
		}
	}
	
	return maxP; 
}

3评选最牛群主v1.0(4分)

题目内容:
现在要评选最牛群主,已知有3名最牛群主的候选人(分别是tom,jack和rose),有不超过1000人参与投票,最后要通过投票评选出一名最牛群主,从键盘输入每位参与投票的人的投票结果,即其投票的候选人的名字,请你编程统计并输出每位候选人的得票数,以及得票数最多的候选人的名字。候选人的名字中间不允许出现空格,并且必须小写。若候选人名字输入错误,则按废票处理。

#include<stdio.h>
#include<string.h>

void inputVote(int *tomVotes, int *jackVotes, int *roseVotes, int n);

int main(){
	int n, tomVotes = 0, jackVotes = 0, roseVotes = 0;
	printf("Input the number of electorates:");
	scanf("%d", &n);
	inputVote(&tomVotes, &jackVotes, &roseVotes, n);
	printf("Election results:\n");
	printf("tom:%d\n", tomVotes);
	printf("jack:%d\n", jackVotes);
	printf("rose:%d\n", roseVotes);
	if(tomVotes > jackVotes){
		if(tomVotes > roseVotes) printf("tom wins");
		else printf("rose wins");
	}
	else {
		if(jackVotes > roseVotes) printf("jack wins");
		else printf("rose wins");
	}
}

void inputVote(int *tomVotes, int *jackVotes, int *roseVotes, int n){
	char str[5];
	char *tom = "tom";
	char *jack = "jack";
	char *rose = "rose";
	for(int i = 0; i < n; i++){
		printf("Input vote %d:", i + 1);
		scanf("%s", str);
		if(strcmp(str, tom) == 0) {
			(*tomVotes)++;
		}else if(strcmp(str, jack) == 0){
			(*jackVotes)++;
		}else if(strcmp(str, rose) == 0){
			(*roseVotes)++;
		}
	}
}
  • 思考一下*vote++;这条语句有什么问题

4星期判断(4分)

题目内容:请输入星期几的第一个字母(不区分大小写)来判断一下是星期几,如果第一个字母一样,则继续判断第二个字母(小写),否则输出“data error”。

#include<stdio.h>
#include<string.h>

void toSmall(char *ch);

int main(){
	char input;
	printf("please input the first letter of someday:\n");
	scanf(" %c", &input);
	toSmall(&input);
	switch(input){
		case 'm':
			printf("monday\n");
			break;
		case 'w':
			printf("wednesday\n");
			break;
		case 'f': 
			printf("friday\n");
			break;
		case 't': 
			printf("please input second letter:\n");
			scanf(" %c", &input);
			if(input == 'h'){
				printf("thursday\n");
			}else if(input == 'u'){
				printf("tuesday\n");
			}else {
				printf("data error\n");
			}
			break;
		case 's': 
			printf("please input second letter:\n");
			scanf(" %c", &input);
			if(input == 'a'){
				printf("saturday\n");
			}else if(input == 'u'){
				printf("sunday\n");
			}else {
				printf("data error\n");
			}
			break;
		default: 
			printf("data error\n");
	}
	return 0;
}

void toSmall(char *ch){
	if(*ch >= 'A'&&*ch <= 'Z'){
		*ch = *ch + 32;
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值