1055 集体照 (25分)
拍集体照时队形很重要,这里对给定的 N 个人 K 排的队形设计排队规则如下:
每排人数为 N/K(向下取整),多出来的人全部站在最后一排;
后排所有人的个子都不比前排任何人矮;
每排中最高者站中间(中间位置为 m/2+1,其中 m 为该排人数,除法向下取整);
每排其他人以中间人为轴,按身高非增序,先右后左交替入队站在中间人的两侧(例如5人身高为190、188、186、175、170,则队形为175、188、190、186、170。这里假设你面对拍照者,所以你的左边是中间人的右边);
若多人身高相同,则按名字的字典序升序排列。这里保证无重名。
现给定一组拍照人,请编写程序输出他们的队形。
输入格式:
每个输入包含 1 个测试用例。每个测试用例第 1 行给出两个正整数 N(≤104,总人数)和 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
样例解答一(超时):
很简单的思路,先排序,然后一左一右输入,最后打印,可惜超时了。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
public class Main {
static class People implements Comparable<People>{
String name;
int height;
public People(String name, int height) {
this.name = name;
this.height = height;
}
public int compareTo(People p) {
if(this.height<p.height)
return -1;
else if(this.height>p.height)
return 1;
else
return p.name.compareTo(this.name);
}
}
public static void main(String[] args) throws Exception{
BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
String[] s = bf.readLine().split(" ");
int n = Integer.parseInt(s[0]);
int k = Integer.parseInt(s[1]);
People[] peoples = new People[n];
for(int i=0;i<n;i++) {
String[] str = bf.readLine().split(" ");
peoples[i] = new People(str[0],Integer.parseInt(str[1]));
}
bf.close();
Arrays.sort(peoples);
int m = n/k;
for(int i=k;i>=1;i--) {
int len=0;
int index=0;
if(i==k) {
len=n-k*m+m;
index=n-1;
}else {
len=m;
index=i*m-1;
}
People[] temp = new People[len];
int left = len/2;
int right = len/2;
temp[left] = peoples[index--];
left--;
right++;
while(left>=0&&right<len) {
temp[left--]=peoples[index--];
temp[right++]=peoples[index--];
}
if(left>=0)
temp[left]=peoples[index];
else if(right<len)
temp[right]=peoples[index];
for(int j=0;j<len-1;j++) {
System.out.print(temp[j].name+" ");
}
System.out.println(temp[len-1].name);
}
}
}
样例解答二:
参考大佬代码,这个Reader 看的不是很懂。
import java.util.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
public class Main {
static class Node implements Comparable<Node> {
private int length;
private String name;
public Node(String name, int length) {
this.name = name;
this.length = length;
}
@Override
public int compareTo(Node o) {
if (this.length > o.length) {
return 1;
} else if (this.length == o.length) {
return o.name.compareTo(this.name);
} else {
return -1;
}
}
}
public static void main(String[] args) throws IOException {
Reader.init(System.in);
int persons = Reader.nextInt();
int group = Reader.nextInt();
List<Node> list = new ArrayList<>(persons);
for (int i = 0; i < persons; i++) {
list.add(new Node(Reader.next(), Reader.nextInt()));
}
Collections.sort(list);
Stack<String> strings = new Stack<>();
int person = persons / group;
for (int i = 0; i < group; i++) {
// 不是最后一排
if (i != group - 1) {
StringBuilder sb = new StringBuilder(list.get(((i + 1) * person - 1)).name + " ");
boolean flag = false;
for (int j = (i + 1) * person - 2; j >= i * person ; j--) {
if (flag) {
// 插入在右边
sb.append(list.get(j).name).append(" ");
flag = false;
} else {
// 插入在左边
sb.insert(0, list.get(j).name + " ");
flag = true;
}
}
// 将产生的结果存储到栈中,并将两边的空格给去掉
strings.push(sb.toString().trim());
} else {
StringBuilder sb = new StringBuilder(list.get(list.size() - 1).name + " ");
boolean flag = false;
for (int j = list.size() - 2; j >= i * person ; j--) {
if (flag) {
sb.append(list.get(j).name).append(" ");
flag = false;
} else {
sb.insert(0, list.get(j).name + " ");
flag = true;
}
}
strings.push(sb.toString().trim());
}
}
while (!strings.isEmpty()) {
System.out.println(strings.pop());
}
}
}
class Reader {
static BufferedReader reader;
static StringTokenizer tokenizer;
/** call this method to initialize reader for InputStream */
static void init(InputStream input) {
reader = new BufferedReader(new InputStreamReader(input));
tokenizer = new StringTokenizer("");
}
/** get next word */
static String next() throws IOException {
while (!tokenizer.hasMoreTokens())
//TODO add check for eof if necessary
tokenizer = new StringTokenizer(reader.readLine());
return tokenizer.nextToken();
}
static int nextInt() throws IOException {
return Integer.parseInt(next());
}
}
``