前言
正文
参考题解
#include<iostream>
#include<algorithm>
using namespace std;
/* 题意:给定n个人,k行,求拍团体照片时的每个人的位置安排。 站位规则: 1、每行站的人数为n/k,(向下取整),多余出来的人数n%k全部放到最后一行 2、站在越后面行中的每一个人身高都比前面行中的人高 3、在每一行中,这一行中最高的人站在中间的位置(m/2+1),m是每一行的人数。 其余的人按照高度依次站在最高的人的右手边,左手边,右手边,....(身高相同的人按照姓名 字典序升序排序,保证没有完全相同名字的人)。假设我们是摄像师,站在这些人对面,那么每行 最高的人的右手边就是我们的左手边。 同理最高的人的左手边就是我们的右手边 思路: 1、除去最后一行外,每一行人数都是n/k,最后一行人数为n/k+n%k。 2、首先需要按照身高和姓名进行排序,这里考虑使用结构体数组来保存所有人 3、根据摆放规则进行摆放即可 */
const int N=1e4+10;
struct Student{
string name;
int height;
}stu[N];
bool cmp(Student a,Student b){//这里之所以按照降序排序,是因为后面的代码是从后往前遍历
if(a.height!=b.height)return a.height<b.height;
else return a.name>b.name;
}
int main(){
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++){
cin>>stu[i].name>>stu[i].height;
}
sort(stu,stu+n,cmp);
int cnt=n/k,rear=n/k+n%k;
for(int i=0;i<k;i++){
int mid,left,right,r;
if(i==0){//最后一行
string a[rear+100];
mid=rear/2+1;
left=mid-1,right=mid+1;
r=n-1;
a[mid]=stu[r].name;
for(int j=r-1;j>=r-rear+1;){
if(left>=0){//要加判断,防止越界
a[left--]=stu[j].name;
}
if(right<=rear){
a[right++]=stu[j-1].name;
}
j-=2;
}
cout<<a[1];
for(int j=2;j<=rear;j++){
cout<<" "<<a[j];
}
n-=rear;
cout<<endl;
}else{//出最后一行外前面的行
string a[cnt+100];
mid=cnt/2+1;
left=mid-1,right=mid+1;
r=n-1;
a[mid]=stu[r].name;
for(int j=r-1;j>=r-cnt+1;){
if(left>=0){
a[left--]=stu[j].name;
}
if(right<=cnt){
a[right++]=stu[j-1].name;
}
j-=2;
}
cout<<a[1];
for(int j=2;j<=cnt;j++){
cout<<" "<<a[j];
}
n-=cnt;
cout<<endl;
}
}
return 0;
}