【题解】【AcWing】1599. 合影

115 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

1599. 合影

原题传送:AcWing 1599. 合影

合影时队形非常重要,给出 NN 个人排成 KK 行的规则,如下所示:

  • 每行的人数必须为 N/KN/K (向下取整),所有多余的人(如果有)都放到最后一行;
  • 位于后排的所有人都不得矮于位于前排的任何人;
  • 在每一行中,最高的人站在该行的中心位置(定义为位置 (m/2+1)(m/2+1) ,位置从1开始编号,其中 mm 是该行的总人数,除法结果向下取整);
  • 在每一行中,其他人必须按照其身高非递增顺序依次排入该行,交替地将他们的位置先安排到最高人的右侧,然后再安排到最高人的左侧(例如,假设五个人的身高为 190188186175170190、188,186、175、170 ,最终阵型将是 175188190186170175、188、190、186、170 。在这里,我们假设你面对着合影人员,因此你的左手边位置其实是最高人的右手边位置。);
  • 当许多人的身高相同时,必须按姓名的字典序升序进行排序,保证所有人的姓名不重复。

现在,给定一群人的相关信息,请你将他们的合照队形排好。

输入格式

第一行包含两个整数, NN 表示总人数, KK 表示排成的行数。

接下来 NN 行,每行包含一个人的姓名和身高。

姓名是长度不超过 88 的由大小写字母构成的字符串,身高是范围在 [30,300][30,300] 的整数。

输出格式

输出排好的合影队形,即在 KK 行输出人员姓名。

名字之间用空格隔开,行尾不得由多余空格。

注意,由于你面对着合影人员,因此,后排的人在上方输出,前排的人在下方输出。

数据范围

1N1041 \le N \le 10^4 , 1K101 \le K \le 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 People
{
	string id;
	int height;
	
	bool operator< (const People &t)const
	{
		if(height != t.height)
			return height > t.height;
		return id < t.id;
	}
}p[N];

int n, k;
string line[N];

int main()
{	
	cin >> n >> k;
	for(int i = 0; i < n; i++)
	{
		cin >> p[i].id >> p[i].height;
	}
	sort(p, p + n);
	
	for(int i = 0, j = 0; i < k; i++)
	{
		int len = n / k;
		if(!i)
			len += n % k;
		for(int r = len / 2 + 1, l = r - 1; l > 0 || r <= len; l--, r++)
		{
			if(r <= len)
				line[r] = p[j++].id;
			if(l > 0)
				line[l] = p[j++].id;
		}
		
		cout << line[1];
		for(int u = 2; u <= len; u++)
			cout << " " << line[u]; 
		cout << endl; 
	}
	
	return 0;
}