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 }
View Code

  迷惑点:审题时以为同样身高的字母序是要按一排从左到右来算的,看了参考后才知道是一左一右加入的时候按字母序加入

参考FROM:https://www.cnblogs.com/andywenzhi/category/859103.html

原文地址:https://www.cnblogs.com/a982961222/p/12362650.html