本文結合PTA專項練習帶領讀者掌握結構體,刷題為主注釋為輔,在代碼中理解思路,其它不做過多敘述。
目錄
- 6-1 選隊長
- 6-2 按等級統計學生成績
- 6-3 學生成績比高低
- 6-4 綜合成績
- 6-5 利用“選擇排序算法“對結構體數組進行排序
- 6-6 結構體的最值
- 6-7 復數相乘運算
- 7-5 一幫一
- 7-6 考試座位號
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 6typedef 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 10struct 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 10struct 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);elseprintf("%.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]);}}}
}