题目链接:PAT【甲级】1109
题目简述::拍集体照时队形很重要,这里对给定的N个人K排的队形设计排队规则如下:
1、每排人数为N/K(向下取整),多出来的人全部站在后一排;
2、后排所有人的个子都不比前排任何人矮;
3、每排中高者站中间(中间位置为m/2+1,其中m为该排人数,除法向下取整);每排其他人以 间人为轴,按身高非增序,先右后左交替入队站在中间人的两侧(例如5人身高为190、188、186、 175、170,则队形为175、188、190、186、170。这里假设你面对拍照者,所以你的左边是中间人的右边);若多人身高相同,则按名字的字典序升序排列。
#include<bits/stdc++.h>
using namespace std;
struct node{
string name;
int height;
bool operator < (const node& p){
return height == p.height ? name > p.name : height < p.height;//切记身高一样时,名字要递减次序排列,这是与下面的插入过程进行配合了的
}
};
vector<node> v;
deque<node> ans[1000];
int main(){
string id;
int n, k, u;
cin >> n >> k;
for (int i = 0; i < n;i++){
cin >> id >> u;
v.push_back({id, u});
}
sort(v.begin(), v.end());
int h = 0, m = n / k;
for (h = 0; h < k - 1;h++){//因为只有k行,那么先进行k-1行插入,剩下的全插入第k行即可
int j = 0;
for (int i = (h + 1) * m - 1; i >= h * m;i--){//倒序插入
if(j % 2 == 0)//模拟插入过程
ans[h].push_back(v[i]);
else
ans[h].push_front(v[i]);
j++;
}
}
for (int i = v.size() - 1, j = 0; i >= h * m;i--){
if(j % 2 == 0)
ans[h].push_back(v[i]);
else
ans[h].push_front(v[i]);
j++;
}
for (int i = h; i >= 0;i--){
cout << ans[i][0].name;
for (int j = 1; j < ans[i].size();j++)
cout << " " << ans[i][j].name;
cout << endl;
}
return 0;
}
幸亏数据量不大,不过打了也没问题。很直观想到了双端队列deque
,模拟插入过程即可。柳神她是直接排列的,我一开始也这样想,但觉得实现挺难的,就用了这个数据结构。