1055 集体照 java满分题解

题目链接👉1055 集体照 (25分)

问题描述:

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

  • 每排人数为 N/K(向下取整),多出来的人全部站在最后一排;
  • 后排所有人的个子都不比前排任何人矮; 每排中最高者站中间(中间位置为 m/2+1,其中 m 为该排人数,除法向下取整);
  • 每排其他人以中间人为轴,按身高非增序,先右后左交替入队站在中间人的两侧(例如5人身高为190、188、186、175、170,则队形为175、188、190、186、170。这里假设你面对拍照者,所以你的左边是中间人的右边);
  • 若多人身高相同,则按名字的字典序升序排列。这里保证无重名。

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


输入格式:

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


输出格式:

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



解题思路:

  1. 把所有人的身高和名字存放在一个数组中peopleArr中,将所有人按照升高降序(这样就能保证遍历数组时是由身高从高到底的顺序进行遍历)的方式进行排列,若多人身高相同,则按名字的字典序升序排列。
  2. 从数组第一个元素开始每行按照每排的人数进行输出相应的人的名字

解题步骤:

第一步: 非常简单,只需要创建people类,里面存放有人民和身高两中属性,再实现Comparable接口即可

第二步: 就稍稍复杂了些,由于最后一排的人数可能会和其他排的人数不同,因此我们先单独输出最后一排,再来处理其他排。那么该怎么按照规定的方式安排一排中的位置呢?
按照题目意思,我们先创建一个用来存储最后一排人的名字的数组outPutLast,为了方便确定每个人的位置,我把数组的长度设置为(lastRowNum+1),以最后一排的身高为:190、188、186、175、170 为例,按照题目意思,我们先确定身高最高的人的位置mid = lastRowNum/2+1,然后确定mid左右两边的位置,元素在peopleArr中的下标与mid相差偶数倍的元素均按照原来的数组的顺序存放在mid的右边,元素在peopleArr中的下标与mid相差奇数数倍的元素均按照原来的数组的逆序存放在mid的左边。

满分代码:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.Arrays;

class people implements Comparable{
	String name;
	int height;
	public people(String name, int height) {
		this.name = name;
		this.height = height;
	}
	public int compareTo(Object o) {
		people p = (people)o;
		if(this.height!=p.height) {
			return -(this.height-p.height);
		}else {
			return this.name.compareTo(p.name);
		}
	}	
}

public class Main {
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StreamTokenizer token = new StreamTokenizer(br);
		token.nextToken();
		int n = (int)token.nval;
		token.nextToken();
		int m = (int)token.nval;
		people[] peopleArr = new people[n];
		
		for(int i=0; i<n; i++) {
			token.nextToken();
			String name = token.sval;
			token.nextToken();
			int height = (int)token.nval;
			
			peopleArr[i] = new people(name, height);
		}
		Arrays.sort(peopleArr);
		
		int lastRowNum = n/m+n%m;
		int eachRowNum = n/m;
		String[] outPutLast = new String[lastRowNum+1];
		
		
		int mid = lastRowNum/2+1;
		int left = mid-1;
		int right = mid+1;
		outPutLast[mid] = peopleArr[0].name;
		for(int index=1; index<lastRowNum; index++) {
			if(index%2==0) {
				outPutLast[right++] = peopleArr[index].name;
			}else {
				outPutLast[left--] = peopleArr[index].name;
			}
		}
		
		for(int k=1; k<=lastRowNum; k++) {
			if(k==1) {
				System.out.print(outPutLast[k]);	
			}else {
				System.out.print(" "+outPutLast[k]);
			}
		}
		System.out.println();
		
		String[] outPutEach = new String[eachRowNum+1];
		
		
		for(int borderLeft=lastRowNum; borderLeft<=n-eachRowNum; borderLeft+=eachRowNum) {
			int borderRight = borderLeft+eachRowNum-1;
			int Mid = eachRowNum/2+1;
			
			int Left = Mid-1;
			int Right = Mid+1;
			int j = borderLeft+1;
			
			outPutEach[Mid] = peopleArr[borderLeft].name;
			for(; j<=borderRight; j++) {
				if((j-borderLeft)%2==0) {
					outPutEach[Right++] = peopleArr[j].name;
				}else {
					outPutEach[Left--] = peopleArr[j].name;
				}
			}
			for(int k=1; k<=eachRowNum; k++) {
				if(k==1) {
					System.out.print(outPutEach[k]);
				}else {
					System.out.print(" "+outPutEach[k]);
				}
				
			}
			System.out.println();
		}
	}
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值