PAT(B) 1055 集体照(Java)

题目链接:1055 集体照 (25 point(s))

题目描述

拍集体照时队形很重要,这里对给定的 N 个人 K 排的队形设计排队规则如下:

  • 每排人数为 N/K(向下取整),多出来的人全部站在最后一排;

  • 后排所有人的个子都不比前排任何人矮;

  • 每排中最高者站中间(中间位置为 m/2+1,其中 m 为该排人数,除法向下取整);

  • 每排其他人以中间人为轴,按身高非增序,先右后左交替入队站在中间人的两侧(例如5人身高为190、188、186、175、170,则队形为175、188、190、186、170。这里假设你面对拍照者,所以你的左边是中间人的右边);

  • 若多人身高相同,则按名字的字典序升序排列。这里保证无重名。

现给定一组拍照人,请编写程序输出他们的队形。

输入格式

每个输入包含 1 个测试用例。每个测试用例第 1 行给出两个正整数 N(≤10​4​​,总人数)和 K(≤10,总排数)。随后 N 行,每行给出一个人的名字(不包含空格、长度不超过 8 个英文字母)和身高([30, 300] 区间内的整数)。

输出格式

输出拍照的队形。即K排人名,其间以空格分隔,行末不得有多余空格。注意:假设你面对拍照者,后排的人输出在上方,前排输出在下方。

输入样例

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

分析?

没有什么好分析的,今天早上看了一篇 Java 函数优雅之道『阿里云云栖社区』,所以突发奇想,试着运用了一下。结果代码就变得这么长了。。。貌似代码可阅读性增强了???

如果出现 TLE ,多提交几次就行。我的也就比规定时间短了 7ms。擦边过。。。

Java代码

/**********************************************************************************
Submit Time			Status		Score	Problem	Compiler		Run Time	User
8/26/2019, 16:41:44	Accepted	25		1055	Java (openjdk)	393 ms		wowpH
**********************************************************************************/
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Main {
	private static BufferedReader input;	// 输入流
	private static int totalPeople;			// 总人数
	private static int totalRows;			// 总行数

	private static BufferedReader getBufferedReader() {// 获取输入流
		InputStreamReader isr = new InputStreamReader(System.in);
		return new BufferedReader(isr);
	}

	private static void setTotalNumber() throws Exception {// 设置总人数和总排数
		String str = input.readLine();
		String[] arr = str.split(" ");
		totalPeople = Integer.parseInt(arr[0]);	// 总人数
		totalRows = Integer.parseInt(arr[1]);	// 总排数
	}

	private static People[] getPeople() throws Exception {// 获取所有人的信息
		People[] people = new People[totalPeople];// 保存所有人
		for (int i = 0; i < totalPeople; ++i) {
			people[i] = new People();
			String str = input.readLine();	// 读取一行信息
			String[] arr = str.split(" ");
			people[i].setName(arr[0]);		// 设置姓名
			int height = Integer.parseInt(arr[1]);
			people[i].setHeight(height);	// 设置身高
		}
		return people;						// 返回所有人
	}

	private static void outputFormation(People[] people) {// 输出队形
		int rowNumber = totalPeople / totalRows;// 每排的人数
		int from = 0;// 每排的起始下标(闭),默认为最后一排的起始下标
		// 每排的结束下标(开),默认为最后一排的结束下标
		int to = rowNumber + totalPeople % totalRows;
		for (int i = 0; i < totalRows; ++i) {// 所有排
			List<People> row = getRowsPeople(people, from, to);// 获取一排的人
			outputRow(row);		// 输出这一排的人的姓名

			from = to;			// 下一排的起始下标
			to += rowNumber;	// 下一排的结束下标
		}
	}

	private static List<People> getRowsPeople(	People[] people, // 所有人
												int from, // 起始下标(闭)
												int to) {// 结束下标(开)
		int length = to - from;// 这一排的人数
		List<People> row = new ArrayList<People>(length);// 初始化长度为length的列表
		boolean dir = true;// 插入列表的方向,true表示在末尾插入
		for (int i = from; i < to; ++i) {
			if (dir) {
				row.add(people[i]);		// 列表末尾插入
				dir = false;			// 改变方向为首部插入
			} else {
				row.add(0, people[i]);	// 列表首部插入
				dir = true;				// 改变方向为末尾插入
			}
		}
		return row;// 返回这一排的人
	}

	private static void outputRow(List<People> row) {// 输出row这一排的人
		int length = row.size();
		for (int i = 0; i < length; ++i) {
			if (i > 0) {
				System.out.print(" ");// 不是第一个人,前面输出空格
			}
			People people = row.get(i);
			String name = people.getName();
			System.out.print(name);
		}
		System.out.println();
	}

	public static void main(String[] args) throws Exception {
		input = getBufferedReader();	// 获取输入流

		setTotalNumber();				// 设置总人数和总排数

		People[] people = getPeople();	// 获取所有人
		Arrays.sort(people);			// 排序

		outputFormation(people);		// 输出队形
	}
}

class People implements Comparable<People> {// 人
	private String name;	// 姓名
	private int height;		// 身高

	public String getName() {			// 获取姓名
		return name;
	}

	public void setName(String name) {	// 设置姓名
		this.name = name;
	}

	public int getHeight() {			// 获取身高
		return height;
	}

	public void setHeight(int height) {	// 设置身高
		this.height = height;
	}

	@Override
	public int compareTo(People o) {
		int anotherHeight = o.getHeight();	// 别人的身高
		if (height != anotherHeight) {		// 身高不等
			return anotherHeight - height;	// 身高降序
		}
		String anotherName = o.getName();	// 别人的姓名
		return name.compareTo(anotherName);	// 姓名字典序升序
	}
}

提交结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值