PAT甲级1109.

目录

A1109

题目

样例

输入:

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

思路和坑点

  思路:
  显然这里需要对学生进行排序,根据排序结果进行位置的安排。第一步需要确定每一排的人数,因为剩余的直接都放在最后一排。假如我们以摄影师的角度看待学生位置,先放中间,然后再放摄影师角度的左边,再放摄影师角度的右边,直到这一排的学生放置满员。这里给出的思路是使用双指针,先放中间位置,然后依次放两次,判断边界就是左侧放置完毕,因为按照题目给出的条件,摄影师角度的左侧人数一定小于大于等于右侧,所以只需要判断左侧即可。

AC代码

#include<bits/stdc++.h>
using namespace std;
typedef struct student{                     //学生信息结构体,名字和身高
    string name;
    int high;
}STU;
bool cmp(STU &a,STU &b){                    //对学生的排序函数,先根据身高从高到低排序,再根据名字字典序排序
    if(a.high!=b.high) return a.high>b.high;
    else return a.name<b.name;
}
int main(){
#ifdef ONLINE_JUDGE
#else
    freopen("1.txt", "r", stdin);
#endif 
    int N,K;
    scanf("%d %d",&N,&K);
    STU DATA[N];
    for(int i=0;i<N;i++)                    //读入数据
        cin>>DATA[i].name>>DATA[i].high;
    sort(DATA,DATA+N,cmp);                  //按照身高从高到低排序,同身高按照名字字典序排列
    vector< vector<string> > out(K);        //输出的二维数组
    int num=N/K;                            //计算每一排人数
    for(int i=0;i<K;i++){                   //初始化每一排数组大小
        if(i==0) out[i].resize(N-(K-1)*num);//如果有剩余放在最后一排
        else out[i].resize(num);
    }
    num=0;                                  //遍历学生数组的指针
    for(int i=0;i<K;i++){                   
        int cnt=out[i].size();              //获取每一排人数
        int mid=cnt/2;                      //计算中间位置,题目中从1开始,如果这里用下标表示,则恰好不用+1
        out[i][mid]=DATA[num++].name;       //放置中间位置
        int l=mid,r=mid;                    //左右两侧的位置指针,初始化为中间位置
        while(1){
            l--,r++;                        
            if(l>=0) out[i][l]=DATA[num++].name;    //在合法范围内放置,先放置摄影师视角的左侧
            if(r<cnt)out[i][r]=DATA[num++].name;    //再放置摄影师视角的右侧
            if(l<0) break;                  //显然左侧的人数大于等于右侧(以摄影师视角的左右侧),所以只判定左侧到达边界说明这一排站位结束
        }
    }
    for(int i=0;i<K;i++){                   //输出结果并控制格式
        for(int j=0;j<out[i].size();j++){
            if(j) putchar(' ');
            cout<<out[i][j];
        }
        putchar('\n');
    }
    return 0;
}