PTA甲级 1109 Group Photo (25point(s))

强烈推荐,刷PTA的朋友都认识一下柳神–PTA解法大佬

本文由参考于柳神博客写成

柳神的CSDN博客,这个可以搜索文章

柳神的个人博客,这个没有广告,但是不能搜索

还有就是非常非常有用的 算法笔记 全名是

算法笔记  上级训练实战指南		//这本都是PTA的题解
算法笔记

PS 今天也要加油鸭

在这里插入图片描述

题目原文

Formation is very important when taking a group photo. Given the rules of forming K rows with N people as the following:

  • The number of people in each row must be N/K (round down to the nearest integer), with all the extra people (if any) standing in the last row;
  • All the people in the rear row must be no shorter than anyone standing in the front rows;
  • In each row, the tallest one stands at the central position (which is defined to be the position (m/2+1), where m is the total number of people in that row, and the division result must be rounded down to the nearest integer);
  • In each row, other people must enter the row in non-increasing order of their heights, alternately taking their positions first to the right and then to the left of the tallest one (For example, given five people with their heights 190, 188, 186, 175, and 170, the final formation would be 175, 188, 190, 186, and 170. Here we assume that you are facing the group so your left-hand side is the right-hand side of the one at the central position.);
  • When there are many people having the same height, they must be ordered in alphabetical (increasing) order of their names, and it is guaranteed that there is no duplication of names.

Now given the information of a group of people, you are supposed to write a program to output their formation.

Input Specification:

Each input file contains one test case. For each test case, the first line contains two positive integers N (≤104), the total number of people, and K (≤10), the total number of rows. Then N lines follow, each gives the name of a person (no more than 8 English letters without space) and his/her height (an integer in [30, 300]).

Output Specification:

For each case, print the formation – that is, print the names of people in K lines. The names must be separated by exactly one space, but there must be no extra space at the end of each line. Note: since you are facing the group, people in the rear rows must be printed above the people in the front rows.

Sample Input:

10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159

Sample Output:

Bob Tom Joe Nick
Ann Mike Eva
Tim Amy John

PS:

最近自己写的第二题,题目就看不下去.

老实读下去吧(妈的,给自己来一拳.这个都读不下去的废物).

生词如下:

Formation 编队

alphabetical 字母顺序

翻译如下:

这个是我自己理解+谷歌翻译的结果.

现在又N个人要去拍照.分成了K行.

然后要求如下:

① 每行的人数都要是N/K个人.然后多的人都放在最后一行

② 后排的行.一定要比前面的行高

③ 最高的人要站在中间–就是中位数

④ 然后就是第二第三站在最高的左右.

在每一行中,其他人都必须按照其身高不升序进入该行,交替地将他们的位置先移到最高人的右侧,然后再移至左侧(例如,假设五个人的身高分别为190、188, 186、175和170,最终阵型将是175、188、190、186和170。在这里,我们假设您正面对该组,因此您的左手边是中央那一组的右手边 位置。);

说人话,就是全部进入之后,逆置一下.

⑤ 如果好几个人身高一样,那么就按照字母的增序.

思路如下:

一开始我想用map写的,但是想了想.map排序不是很好排序.然后看了看柳神的博客,决定用柳神的代码写

柳神还是柳神.大佬就是大佬.

贴一下,柳神的思路:

*分析:建立结构体node,里面包含string类型的姓名name和int类型的身高height~将学生的信息输入到node类型的vector数组stu中~然后对stu数组进行排序(cmp函数表示排序规则,如果身高不等,就按照身高从大到小排列;如果身高相等,就按照名字从小到大的字典序排列~)然后用while循环排列每一行,将每一行应该排列的结果的姓名保存在ans数组中~*

因为是面对拍照者,后排的人输出在上方,前排输出在下方,每排人数为N/K(向下取整),多出来的人全部站在最后一排,所以第一排输出的应该是包含多出来的人,所以while循环体中,当row == k时,表示当前是在排列第一行,那么这一行的人数m应该等于总人数n减去后面的k列*(k-1)行,即m = n – n / k * (k-1);如果不是第一行,那么m直接等于n / k;最中间一个学生应该排在m/2的下标位置,即ans[m / 2] = stu[t].name;然后排左边一列,ans数组的下标 j 从m/2-1开始,一直往左j–,而对于stu的下标 i,是从t+1开始,每次隔一个人选取(即i = i+2,因为另一些人的名字是给右边的),每次把stu[i]的name赋值给ans[j–];排右边的队伍同理,ans数组的下标 j 从m/2 + 1开始,一直往右j++,stu的下标 i,从t+2开始,每次隔一个人选取(i = i+2),每次把stu[i]的name赋值给ans[j++],然后输出当前已经排好的ans数组~每一次排完一列row-1,直到row等于0时退出循环表示已经排列并输出所有的

代码如下:

#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
struct node {
	string name;
	int height;
};
bool cmp(node a,node b) {							//排序的比较代码
	if (a.height != b.height)	return a.height > b.height;
	else
		return a.name < b.name;
}
int main(void) {
	int N, K;
	scanf("%d%d", &N, &K);
	vector<node> data(N);
	for (int i = 0; i < N; ++i) {
		string name;
		int height;
		cin >> name >> height;
		data[i].name = name;
		data[i].height = height;
	}
	sort(data.begin(), data.end(), cmp);		//排序
	int t = 0, row = K;
	int m = 0;
	while (row) {
		if (row == K) {
			m =  N / K +N%K;
		}
		else {
			m = N / K;
		}
		vector<string> ans(m);
		ans[m / 2] = data[t].name;
		//左边一列
		int j = m / 2 - 1;
		for (int i = t + 1; i < t + m; i = i + 2)
			ans[j--] = data[i].name;
		//右边一列
		j = m / 2 + 1;
		for (int i = t + 2; i < t + m; i = i + 2)
			ans[j++] = data[i].name;
		//输出当前排
		cout << ans[0];
		for (int i = 1; i < m; i++) {
			cout << " " << ans[i];
		}
		cout << endl;
		t = t + m;
		row--;
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值