PTA 集体照(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(≤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

样例解答一(超时):

很简单的思路,先排序,然后一左一右输入,最后打印,可惜超时了。

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());
    }
}


``
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值