zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    bzoj3159: 决战
    Codeforces Round #516 (Div. 1, by Moscow Team Olympiad) C
    Codeforces Round #516 (Div. 1, by Moscow Team Olympiad) B
    Codeforces Round #516 (Div. 1, by Moscow Team Olympiad) A
    loj 6401 字符串
    BZOJ5194 雪地靴
    BZOJ 4709 柠檬
    BZOJ 3343 魔法
    [8月16日绍兴]试剂
    设备塔
  • 原文地址:https://www.cnblogs.com/a982961222/p/12362650.html
Copyright © 2011-2022 走看看