PAT_甲级_1109 Group Photo (25point(s)) (C++)【模拟】
原创
©著作权归作者所有:来自51CTO博客作者再见萤火虫IT的原创作品,请联系作者获取转载授权,否则将追究法律责任
目录
1,题目描述
题目大意
2,思路
数据结构
算法
3,AC代码
4,解题过程
1,题目描述
Sample Input:
10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159
Sample Output:
Bob Tom Joe Nick
Ann Mike Eva
Tim Amy John
题目大意
将N个人按照规则排成K行站队。规则如下:
“我”面向队伍,队伍第一排最矮,往后逐渐增高;
- The number of people in each row must be N/K (round down to the nearest integer), with all the extra people (if any) standing in the last row:每一行的人数为N/K向下取整(正常除即可),多出来的人全部站在最后一行;
- All the people in the rear row must be no shorter than anyone standing in the front rows:后一排的比前一排的任何一个人高;
- In each row, the tallest one stands at the central position (which is defined to be the position (m/2+1), where m is the total number of people in that row, and the division result must be rounded down to the nearest integer):最高的人站的位置,假如一行有3个人,编号0-2,tallest站在3/2=1,假如一行有4个人,tallest站在4/2=2;
- In each row, other people must enter the row in non-increasing order of their heights, alternately taking their positions first to the right and then to the left of the tallest one :“我”面向队伍,4th 2th 1th 3th / 2th 1th 3th;
- When there are many people having the same height, they must be ordered in alphabetical (increasing) order of their names:当身高相等时,名字更“大”的同学更“矮”;
2,思路
数据结构
- struct node{
string name;
int height;
}data[10006];所有人的身高和名字数据; - node infor[K][lenRear]:队伍站位;
算法
- 接收数据至data:
- 从低到高排序:
- 记录每一行最低的人的位置(便于定位最高的人tallest),每次排一行(一行中左右交替赋值),从前往后:
- 输出
3,AC代码
#include<bits/stdc++.h>
using namespace std;
struct node{
string name;
int height;
}data[10006];
bool cmp1(node a, node b){
if(a.height != b.height)
return a.height < b.height;
else
return a.name > b.name; //注意排序规则
}
int main(){
#ifdef ONLINE_JUDGE
#else
freopen("1.txt", "r", stdin);
#endif // ONLINE_JUDGE
int N, K;
scanf("%d %d", &N, &K);
node n;
for(int i = 0; i < N; i++){
cin>>n.name>>n.height;
data[i] = n;
}
sort(data, data + N, cmp1);
int len = N / K, lenRear = len + N % K, index = 0;//index每一行的最低的人
node infor[K][lenRear];
int tallest, left, right; //left左指针 right右指针 分别指向将要赋值的位置
bool flag; //判断左右 false左 true右
for(int i = 0; i < K; i++){ //K行
if(i != K - 1){
tallest = index + len - 1; //当前行最高的人在data中的编号
left = len / 2 - 1;right = len / 2;
}else{
tallest = N - 1;
left = lenRear / 2 - 1;right = lenRear / 2;
}
flag = true; //右1th 左2th 右3th......右左交替!!!
for(int j = 0; j < (i==K-1 ? lenRear:len); j++){
if(flag){
infor[i][right++] = data[tallest--];
flag = false;
}else{
infor[i][left--] = data[tallest--];
flag = true;
}
}
index += len; //index每一行的最低的人
}
for(int i = K - 1; i >= 0; i--){
for(int j = 0; j < (i==K-1 ? lenRear:len); j++){
if(j == 0)
cout<<infor[i][j].name;
else
cout<<' '<<infor[i][j].name;
}
cout<<endl;
}
return 0;
}
4,解题过程
一发入魂