前言

传送门

正文


参考题解

#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;
}