合影时队形非常重要,给出 NN 个人排成 KK 行的规则,如下所示:
每行的人数必须为 N/KN/K(向下取整),所有多余的人(如果有)都放到最后一行;
位于后排的所有人都不得矮于位于前排的任何人;
在每一行中,最高的人站在该行的中心位置(定义为位置 (m/2+1)(m/2+1),位置从1开始编号,其中 mm 是该行的总人数,除法结果向下取整);
在每一行中,其他人必须按照其身高非递增顺序依次排入该行,交替地将他们的位置先安排到最高人的右侧,然后再安排到最高人的左侧(例如,假设五个人的身高为 190、188,186、175、170190、188,186、175、170,最终阵型将是 175、188、190、186、170175、188、190、186、170。在这里,我们假设你面对着合影人员,因此你的左手边位置其实是最高人的右手边位置。);
当许多人的身高相同时,必须按姓名的字典序升序进行排序,保证所有人的姓名不重复。
现在,给定一群人的相关信息,请你将他们的合照队形排好。
输入格式
第一行包含两个整数,NN 表示总人数,KK 表示排成的行数。
接下来 NN 行,每行包含一个人的姓名和身高。
姓名是长度不超过 88 的由大小写字母构成的字符串,身高是范围在 [30,300][30,300] 的整数。
输出格式
输出排好的合影队形,即在 KK 行输出人员姓名。
名字之间用空格隔开,行尾不得由多余空格。
注意,由于你面对着合影人员,因此,后排的人在上方输出,前排的人在下方输出。
数据范围
1≤N≤1041≤N≤104,
1≤K≤101≤K≤10
输入样例:
10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159
输出样例:
Bob Tom Joe Nick
Ann Mike Eva
Tim Amy John
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
struct node{
string id;
int h;
bool operator<(const node&a)const{
if(h!=a.h)return h>a.h;
else return id<a.id;
}
}p[N];
int main(){
int n,k;
cin>>n>>k;
for(int i=0;i<n;i++)cin>>p[i].id>>p[i].h;
sort(p,p+n);
int t=0;//指向p的下标
for(int v=0;v<k;v++){//输出多少行
int len=n/k;
if(v==0)len+=n%k;//第一行人数特判
vector<string>s(len+1);//每一行的人数已经固定,不用存着最后一起输出,存一行输出一行
s[len/2+1]=p[t].id;
int j=len/2+2;
for(int r=t+2;r<len+t;r+=2){//注意是小于
s[j++]=p[r].id;
}
j=len/2;
for(int l=t+1;l<len+t;l+=2){
s[j--]=p[l].id;
}
cout<<s[1];
for(int i=2;i<=len;i++){
cout<<' '<<s[i];
}
cout<<endl;
t=t+len;
}
return 0;
}
双指针做法
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 10010;
int n, m;
struct Person
{
string name;
int h;
bool operator< (const Person &t) const
{
if (h != t.h) return h > t.h;
return name < t.name;
}
}p[N];
string line[N];
int main()
{
cin >> n >> m;
for (int i = 0; i < n; i ++ ) cin >> p[i].name >> p[i].h;
sort(p, p + n);
for (int i = 0, j = 0; i < m; i ++ )
{
int len = n / m;
if (!i) len += n % m; // 特判最后一排
for (int r = len / 2 + 1, l = r - 1; l > 0 || r <= len; l --, r ++ )
{
if (r <= len) line[r] = p[j ++ ].name;
if (l > 0) line[l] = p[j ++ ].name;
}
cout << line[1];
for (int k = 2; k <= len; k ++ ) cout << ' ' << line[k];
cout << endl;
}
return 0;
}