1. 题意
照相位置排序,满足如下要求:
- 每行人数必须为 N / K (四舍五入到最接近的整数),所有多余的人(如果有)都位于最后一行;
- 后排的所有人员不得矮于前排的任何人员;
- 在每一行中,最高的行位于中心位置(定义为该位置 (m/ 2 + 1 ),m 是该行中的总人数,除法结果必须向下取整;
- 在每一行中,其他人必须以其身高不升序进入该行,交替地将他们的位置先移到最高人的右侧,然后再移至左侧(例如,假设五个人的身高分别为190、188, 186、175和170,最终阵型将是175、188、190、186和170。在这里,我们假设正面对该组,因此左手边是中央那一组的右手边位置。); 即输出的时候先左边一个再右边一个。
- 当多人的身高相同时,必须按姓名的字母顺序(递增)进行排序,并确保姓名不重复。
2. 代码
- 看了很多解答,还是柳神的代码比较清楚简介。微微修改加注释
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct node {
string name;
int height;
};
bool cmp(const node &a, const node &b) {
return a.height != b.height ? a.height > b.height : a.name < b.name;
}
int main() {
int n, k, m; // n为总人数 k为总行数 m为每行人数
cin >> n >> k;
vector<node> stu;
for (int i = 0; i < n; i++) {
cin >> stu[i].name;
cin >> stu[i].height;
}
sort(stu.begin(), stu.end(), cmp);
int t = 0, row = k; //t控制输出,从0开始,每行加m
while (row--) {
if (row == k) { //最后一排(第一行输出)
m = n - n / k * (k - 1); //人数为 总人数 - 前 k-1 排的人数
} else {
m = n / k; //其余常规输出每排人数
}
string ans[m]; //存储输出结果,每次输出一行
ans[m / 2] = stu[t].name; //最中间(最高的)的学生姓名
// 左边
int j = m / 2 - 1;
for (int i = t + 1; i < t + m; i = i + 2)
ans[j--] = stu[i].name;
// 右边
j = m / 2 + 1;
for (int i = t + 2; i < t + m; i = i + 2)
ans[j++] = stu[i].name;
// 输出当前排
cout << ans[0]; //方便输出,先输出每行第一个
for (int i = 1; i < m; i++)
cout << " " << ans[i];
cout << endl;
t = t + m; //每行输出完毕,加上m输出下一行
}
return 0;
}