本文结合PTA专项练习带领读者掌握结构体,刷题为主注释为辅,在代码中理解思路,其它不做过多叙述。
6-1 选队长
小明最近喜欢玩一款新游戏。在该游戏中,需要组建队伍去完成任务以获取奖励。小明挑出了所有的队员(每个人能力不同),需要一个函数挑出队长(能力最强的队员)。
函数接口定义:
void showCaptain(TeamMember team[], int n);
参数说明:team中从下标0开始存放n个TeamMember,n>0。
函数功能:找出队长并输出其各项信息
裁判测试程序样例:
#include<stdio.h> #include<stdlib.h> #define NAME_LEN 100 #define SEX_LEN 6 typedef struct { int id;//身份证号码 char lastname[NAME_LEN+1];//姓 char firstname[NAME_LEN+1];//名 char sex[SEX_LEN];//性别 double ability; } TeamMember; void showCaptain(TeamMember team[], int n); int main() { TeamMember *team; int n; int i; scanf("%d",&n); team = (TeamMember *)malloc(n*sizeof(TeamMember)); for(i=0;i<n;i++) { scanf("%d %s %s %s %lf",&team[i].id,team[i].lastname, team[i].firstname, team[i].sex, &team[i]. ability); } showCaptain(team, n); return 0; } /* 您提交的代码将放置在这里 */
输入样例:
3
123456 zhang san male 100
123457 li si female 200.5
123458 wang ming male 159.1
输出样例:
123457 li si female 200.50
void showCaptain(TeamMember team[], int n) { double x=team[0].ability;int y=0; for(int i=0;i<n;i++) { if(x<team[i].ability) { x=team[i].ability; y=i; } } printf("%d %s %s %s %.2f",team[y].id,team[y].lastname,team[y].firstname,team[y].sex,team[y].ability); }
6-2 按等级统计学生成绩
本题要求实现一个根据学生成绩设置其等级,并统计不及格人数的简单函数。
函数接口定义:
int set_grade( struct student *p, int n );
其中p是指向学生信息的结构体数组的指针,该结构体的定义为:
struct student{ int num; char name[20]; int score; char grade; };
n是数组元素个数。学号num、姓名name和成绩score均是已经存储好的。set_grade函数需要根据学生的成绩score设置其等级grade。等级设置:85-100为A,70-84为B,60-69为C,0-59为D。同时,set_grade还需要返回不及格的人数。
裁判测试程序样例:
#include <stdio.h> #define MAXN 10 struct student{ int num; char name[20]; int score; char grade; }; int set_grade( struct student *p, int n ); int main() { struct student stu[MAXN], *ptr; int n, i, count; ptr = stu; scanf("%d\n", &n); for(i = 0; i < n; i++){ scanf("%d%s%d", &stu[i].num, stu[i].name, &stu[i].score); } count = set_grade(ptr, n); printf("The count for failed (<60): %d\n", count); printf("The grades:\n"); for(i = 0; i < n; i++) printf("%d %s %c\n", stu[i].num, stu[i].name, stu[i].grade); return 0; } /* 你的代码将被嵌在这里 */
输入样例:
10
31001 annie 85
31002 bonny 75
31003 carol 70
31004 dan 84
31005 susan 90
31006 paul 69
31007 pam 60
31008 apple 50
31009 nancy 100
31010 bob 78
输出样例:
The count for failed (<60): 1
The grades:
31001 annie A
31002 bonny B
31003 carol B
31004 dan B
31005 susan A
31006 paul C
31007 pam C
31008 apple D
31009 nancy A
31010 bob B
int set_grade( struct student *p, int n ) { int count=0; for(int i=0;i<n;i++) { if(p[i].score<=100&&p[i].score>=85) p[i].grade='A'; if(p[i].score<=84&&p[i].score>=70) p[i].grade='B'; if(p[i].score<=69&&p[i].score>=60) p[i].grade='C'; if(p[i].score<=59&&p[i].score>=0) { p[i].grade='D'; count++; } } return count; }
6-3 学生成绩比高低
学生结构体定义如下:
struct Student{ int sid; int C; int English; };
其中sid是学号,C是C语言课程成绩,English是英语课程成绩。学生的成绩按照这样的规则比较:
先比较两门课的总成绩,总成绩高的为优; 若总成绩相同,再比较C语言成绩,C语言成绩高的为优; 若C语言成绩也相同,则说明两名学生成绩相等。
编写函数实现成绩的比较。
函数接口定义:
int compareScore(const struct Student *s1, const struct Student *s2);
其中s1和s2是传入的参数,分别指向两名学生的结构体变量。函数返回值为int型,
若s1所指学生成绩优于s2所指学生,返回1; 若s2所指学生成绩优于s1所指学生,返回-1; 若两学生成绩相等,返回0。
裁判测试程序样例:
/* 此测试程序仅为示例,实际的测试程序可能不同。
注意:实际的测试程序可能有多组输入、进行多次比较,输入格式也有可能不同,
因此不要针对测试程序样例编写代码,而应当编写符合题目要求的函数 */
#include <stdio.h> struct Student{ int sid; int C; int English; }; int compareScore(const struct Student *s1, const struct Student *s2); int main(){ struct Student zs, ls; scanf("%d%d%d", &zs.sid, &zs.C, &zs.English); scanf("%d%d%d", &ls.sid, &ls.C, &ls.English); int r; r = compareScore(&zs, &ls); if(r < 0) printf("Less\n"); else if(r > 0) printf("Greater\n"); else printf("Equal\n"); return 0; } /* 你所编写的函数代码将被嵌在这里 */
输入样例1:
对于样例测试程序的输入格式:
1 95 90
2 90 91
输出样例1:
对于样例测试程序的输出格式:
Greater
输入样例2:
对于样例测试程序的输入格式:
1 90 95
2 95 90
输出样例2:
对于样例测试程序的输出格式:
Less
int compareScore(const struct Student *s1, const struct Student *s2){ if(s1->C+s1->English>s2->C+s2->English) return 1; else if(s1->C+s1->English<s2->C+s2->English) return -1; else if(s1->C+s1->English==s2->C+s2->English) { if(s1->C>s2->C) return 1; else if(s1->C<s2->C) return -1; else if(s1->C==s2->C) return 0; } }
6-4 综合成绩
小明的公司为了招聘新员工设计了一套考试方案。从表达能力、逻辑能力、人文素质、科学素质、计算思维5个方面进行考察。综合成绩 = 表达能力0.4+逻辑能力0.5+人文素质0.3+科学素质0.6+计算思维*0.8。要求定义一个计算综合成绩的函数。
函数接口定义:
double getAverage(Applicant *a);
a中存放一个应聘者的考试成绩。要求返回综合成绩。
裁判测试程序样例:
#include <stdio.h> #include <stdlib.h> typedef struct{ int presentation; int logical; int humanistic; int scientific; int computational; }Applicant; double getAverage(Applicant* a); int main() { Applicant a; double overall; scanf("%d%d%d%d%d", &a.presentation,&a.logical,&a.humanistic,&a.scientific,&a.computational); overall = getAverage(&a); printf("%.2f\n",overall); return 0; }
/* 您提交的代码将放置在这里 */
输入样例:
100 100 100 100 100
输出样例:
260.00
double getAverage(Applicant *a) { double sum=0; sum=0.4*a->presentation+0.5*a->logical+0.3*a->humanistic+0.6*a->scientific+0.8*a->computational; return sum; }
6-5 利用“选择排序算法“对结构体数组进行排序
本题:补充函数 sortByChoose()的剩余部分,其要求是利用选择排序算法根据学生成绩(score)实现对结构体数组元素降序排序。
函数接口定义:
void sortByChoose(struct Student *pData,int n);
裁判测试程序样例:
#include<stdio.h> #include<stdlib.h> #define N 10 struct Student { int num; int score; }; void sortByChoose(struct Student *pData,int n); int main(void) { struct Student data[10],*p; int i; for(p=data,i=0;i<N;i++) { scanf("%d %d",&p->num,&p->score); p++; } sortByChoose(data,N); for (p=data,i=0;i<N;i++) { printf("%2d-%-5d", p->num, p->score); p++; } return 0; } void sortByChoose(struct Student *pData,int n) { struct Student *p1,*p2,*p; int num, score,i,j; for(p1=pData;p1<pData+n-1;p1++) { /* 请在这里填写答案 */ } }
输入样例:
29 90
15 80
87 55
65 84
35 80
33 55
44 79
99 80
89 80
41 55
输出样例:
29-90 65-84 15-80 35-80 99-80 89-80 44-79 87-55 33-55 41-55
p=p1; for(p2=p1+1;p2<pData+n;p2++) { if(p2->score>p->score)//判断 { p=p2; } } if(p!=p1)//交换 { num=p->num; p->num=p1->num; p1->num=num; score=p->score; p->score=p1->score; p1->score=score; }
6-6 结构体的最值
学生类型ST的定义如下:
typedef struct student{ char name[10],id[10]; int gender; int age; double scored; } ST;
编写函数,返回指定学生数组中的男生或女生的最高分的地址(约定:整数0和1分别代表男和女)。
函数接口定义:
ST* MaxST(ST d[],int n,int k);//k=0|1
其中 d 是学生数组的初地址, n是数组的长度, k 是查找的性别描述(值确保是0或1),函数须返回指定类型学生中的最高分者的地址,如果不存在,返回空地址。
裁判测试程序样例:
在这里给出函数被调用进行测试的例子。例如:
#include <stdio.h> #include <stdlib.h> typedef struct student{ char name[10],id[10]; int gender; int age; double scored; } ST; void output(ST *d){//输出一个记录 if(d==NULL) {printf("null\n");return;} printf("%s,%s,%d,%d,%4.2f\n",d->name,d->id,d->gender,d->age,d->scored); } ST* InitData(int n);//从输入设备上输入相关数据,略去不表 ST* MaxST(ST d[],int n,int k);//k=0|1 <--需要完成的函数:找最值 int main(){ int i,n;scanf("%d\n",&n); ST *p=InitData(n); output(MaxST(p,n,0)); output(MaxST(p,n,1)); free(p); return 0; } /* 请在这里填写答案 */
输入样例:
第一行是记录个数,余下若干行是相关数据(以空格分隔,每行一个)。
6
Marry.MK 20201125 0 19 92.86
J.Mark 20201185 0 17 90.93
rouh.M 20201102 1 18 79.51
byi.beee 20201129 1 17 90.28
floyd.Fd 20201150 0 17 81.16
grdda 20201146 1 19 85.52
输出样例:
输出男,女同学中的最高分(只需要找出并返回其地址,输入,输出由测试程序完成)。
Marry.MK,20201125,0,19,92.86
byi.beee,20201129,1,17,90.28
ST* MaxST(ST d[],int n,int k) { double max=-1;//初始化最高分为一个较小的值 int index=-1;//初始化索引为-1,表示不存在满足条件的学生 for(int i=0;i<n;i++) { if(d[i].gender==k)//根据输入的性别条件进行筛选 { if(d[i].scored>max)//找到性别符合条件的学生中的最高分 { max=d[i].scored; index=i;//更新最高分的索引 } } } if(index!=-1) { return &d[index];//返回最高分学生的地址 } else { return NULL;//如果不存在满足条件的学生,返回空地址 } }
6-7 复数相乘运算
本题要求实现一个函数,可计算两个复数相乘的积。
函数接口定义:
PLEX multi(PLEX a,PLEX b);
其中 a 和 b 都是复数,返回值也为复数,值为a*b的值。
裁判测试程序样例:
#include <stdio.h> typedef struct { float re,im; }PLEX; PLEX multi(PLEX a,PLEX b); int main() { PLEX x,y,z; scanf("%f%f",&x.re,&x.im); scanf("%f%f",&y.re,&y.im); z=multi(x,y); if(z.im>=0) printf("%.2f+%.2fi",z.re,z.im); else printf("%.2f%.2fi",z.re,z.im); return 0; } /* 请在这里填写答案 */
输入样例:
1 2
3 4
输出样例:
-5.00+10.00i
PLEX multi(PLEX a,PLEX b) { PLEX T; T.re=a.re*b.re-a.im*b.im; T.im=a.re*b.im+a.im*b.re; return T; }
7-5 一帮一
“一帮一学习小组”是中小学中常见的学习组织方式,老师把学习成绩靠前的学生跟学习成绩靠后的学生排在一组。本题就请你编写程序帮助老师自动完成这个分配工作,即在得到全班学生的排名后,在当前尚未分组的学生中,将名次最靠前的学生与名次最靠后的异性学生分为一组。
输入格式:
输入第一行给出正偶数N(≤50),即全班学生的人数。此后N行,按照名次从高到低的顺序给出每个学生的性别(0代表女生,1代表男生)和姓名(不超过8个英文字母的非空字符串),其间以1个空格分隔。这里保证本班男女比例是1:1,并且没有并列名次。
输出格式:
每行输出一组两个学生的姓名,其间以1个空格分隔。名次高的学生在前,名次低的学生在后。小组的输出顺序按照前面学生的名次从高到低排列。
输入样例:
8
0 Amy
1 Tom
1 Bill
0 Cindy
0 Maya
1 John
1 Jack
0 Linda
输出样例:
Amy Jack
Tom Linda
Bill Maya
Cindy John
#include <stdio.h> int main() { int n;scanf("%d",&n); int sex[n];char name[n][9]; for(int i=0;i<n;i++) { scanf("%d %s",&sex[i],name[i]); } int exist[n]={0}; for(int p=0;p<n/2;p++)//与后面的printf相呼应,保证输出的时候名次高的在前 { for(int q=n-1;q>=n/2;q--) { if(sex[p]!=sex[q]&&exist[p]==0&&exist[q]==0)//如果性别不同且没组过队 { printf("%s %s\n",name[p],name[q]); exist[p]=exist[q]=1; } } } }
7-6 考试座位号
每个 PAT 考生在参加考试时都会被分配两个座位号,一个是试机座位,一个是考试座位。正常情况下,考生在入场时先得到试机座位号码,入座进入试机状态后,系统会显示该考生的考试座位号码,考试时考生需要换到考试座位就座。但有些考生迟到了,试机已经结束,他们只能拿着领到的试机座位号码求助于你,从后台查出他们的考试座位号码。
输入格式:
输入第一行给出一个正整数 N(≤1000),随后 N 行,每行给出一个考生的信息:准考证号 试机座位号 考试座位号。其中准考证号由 16 位数字组成,座位从 1 到 N 编号。输入保证每个人的准考证号都不同,并且任何时候都不会把两个人分配到同一个座位上。
考生信息之后,给出一个正整数 M(≤N),随后一行中给出 M 个待查询的试机座位号码,以空格分隔。
输出格式:
对应每个需要查询的试机座位号码,在一行中输出对应考生的准考证号和考试座位号码,中间用 1 个空格分隔。
输入样例:
4
3310120150912233 2 4
3310120150912119 4 1
3310120150912126 1 3
3310120150912002 3 2
2
3 4
输出样例:
3310120150912002 2
3310120150912119 1
#include <stdio.h> int main() { int n;scanf("%d",&n); char sfz[n][20];int sj[n],ks[n]; for(int i=0;i<n;i++) { scanf("%s",sfz[i]); scanf("%d %d",&sj[i],&ks[i]); } int m;scanf("%d",&m); int chaxun[m]; for(int i=0;i<m;i++) { scanf("%d",&chaxun[i]); int s=chaxun[i]; for(int j=0;j<n;j++) { if(s==sj[j]) { printf("%s %d\n",sfz[j],ks[j]); } } } }