PAT乙级1055-----集体照 (25分)
Posted a982961222
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PAT乙级1055-----集体照 (25分)相关的知识,希望对你有一定的参考价值。
1055 集体照 (25分)
拍集体照时队形很重要,这里对给定的 N 个人 K 排的队形设计排队规则如下:
-
每排人数为 /(向下取整),多出来的人全部站在最后一排;
-
后排所有人的个子都不比前排任何人矮;
-
每排中最高者站中间(中间位置为 /,其中 m 为该排人数,除法向下取整);
-
每排其他人以中间人为轴,按身高非增序,先右后左交替入队站在中间人的两侧(例如5人身高为190、188、186、175、170,则队形为175、188、190、186、170。这里假设你面对拍照者,所以你的左边是中间人的右边);
-
若多人身高相同,则按名字的字典序升序排列。这里保证无重名。
现给定一组拍照人,请编写程序输出他们的队形。
输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出两个正整数 N(≤,总人数)和 K(≤,总排数)。随后 N 行,每行给出一个人的名字(不包含空格、长度不超过 8 个英文字母)和身高([30, 300] 区间内的整数)。
输出格式:
输出拍照的队形。即K排人名,其间以空格分隔,行末不得有多余空格。注意:假设你面对拍照者,后排的人输出在上方,前排输出在下方。
输入样例:
10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159
输出样例:
Bob Tom Joe Nick Ann Mike Eva Tim Amy John
思路:
身高按降序排,同样身高按字母顺序排(要用到strcmp,不是直接比较首字母ASCII值),然后每排先找到中间人位置,以中间人为基准,先左后右依次将排好的序列一个一个加入即可
首次通过代码:
1 #include<stdio.h> 2 #include<string.h> 3 int flag=1; 4 int counter=0; 5 int distance=1; 6 void swap(int *a,int i,int j){//交换数组中下标为i和下标为j的元素 7 int swap=a[i]; 8 a[i]=a[j]; 9 a[j]=swap; 10 } 11 void sort(int *height,int *sorted_num,char name[][10],int student_sum){//学生编号按学生身高的降序进行排列,同等身高的按字母升序排列 12 for(int i=1;i<student_sum;i++) 13 for(int j=i;j>=1;j--){ 14 if(height[j]>height[j-1]){ 15 swap(height,j,j-1); 16 swap(sorted_num,j,j-1); 17 } 18 else if(height[j]==height[j-1]&&strcmp(name[sorted_num[j]],name[sorted_num[j-1]])<0){ //此处可能会出现段错误 19 swap(height,j,j-1); 20 swap(sorted_num,j,j-1); 21 } 22 else break; 23 } 24 } 25 int judge_now_position(int mid_num){ 26 int now_position; 27 if(flag){ 28 flag=0; 29 now_position=mid_num-distance; 30 counter++; 31 32 } 33 else { 34 flag=1; 35 now_position=mid_num+distance; 36 counter++; 37 } 38 if(counter==2) { 39 distance++; 40 counter=0; 41 } 42 return now_position; 43 } 44 int main(){ 45 int student_sum; 46 int row_sum; 47 char name[10002][10];//姓名 48 int height1[10002];//身高 49 int sorted_num[10002];//学生编号 50 int final_num[10002];//最后排好序的学生编号 51 scanf("%d %d",&student_sum,&row_sum); 52 int every_row_sum=student_sum/row_sum; 53 int last_row_sum=every_row_sum+(student_sum-every_row_sum*row_sum); 54 for(int i=0;i<student_sum;i++){ 55 scanf("%s %d",&name[i],&height1[i]); 56 sorted_num[i]=i; 57 } 58 sort(height1,sorted_num,name,student_sum); 59 //最后一排(身高最高)排序 60 int mid_num; 61 int now_position;int now_height_sum; 62 for(int i=0;i<last_row_sum;i++){ 63 //首先判断中间人 64 if(i==0) { 65 mid_num=last_row_sum/2; 66 final_num[mid_num]=sorted_num[0]; 67 } 68 else { 69 //找到要插入的位置 70 now_position=judge_now_position(mid_num); 71 //判断要插入的元素 72 final_num[now_position]=sorted_num[i]; 73 } 74 } 75 76 for(int i=0;i<last_row_sum;i++){ 77 printf("%s",name[final_num[i]]); 78 if(i!=last_row_sum-1) printf(" "); 79 } 80 81 if(last_row_sum<student_sum) 82 printf(" "); 83 else return 0; 84 flag=1;distance=1;counter=0; 85 86 //前排排序 87 for(int i=last_row_sum;i<student_sum;i+=every_row_sum){ 88 for(int j=i;j<i+every_row_sum;j++){ 89 if(j==i){ 90 mid_num=j+every_row_sum/2; 91 final_num[mid_num]=sorted_num[j]; 92 } 93 else{ 94 now_position=judge_now_position(mid_num); 95 final_num[now_position]=sorted_num[j]; 96 } 97 } 98 flag=1;distance=1;counter=0; 99 } 100 for(int i=last_row_sum;i<student_sum;i+=every_row_sum){ 101 for(int j=i;j<i+every_row_sum;j++){ 102 printf("%s",name[final_num[j]]); 103 if(j!=i+every_row_sum-1) printf(" "); 104 } 105 if(i!=student_sum-every_row_sum) printf(" "); 106 } 107 return 0; 108 }
迷惑点:审题时以为同样身高的字母序是要按一排从左到右来算的,看了参考后才知道是一左一右加入的时候按字母序加入
参考FROM:https://www.cnblogs.com/andywenzhi/category/859103.html
以上是关于PAT乙级1055-----集体照 (25分)的主要内容,如果未能解决你的问题,请参考以下文章