PAT 1109 Group Photo [Java]
PAT 1109 Group Photo [Java]
1. 题意
在为集体拍照时,构成规则是非常重要的。给出为N 个人站成K 行的规则如下:
- 每行的人数必须是N/K (向下取整),所有的剩下的人(如果有的话)站在最后一排
- 后一行的人必须不矮于前一行的人
- 每行中,最高的人站在中间的位置(定义成:m/2 + 1),m是该行人的总数, 除法的结果必须向下取整。
- 每行中,其它的人必须按照 从高到矮(non-increasing order) 的顺序依次入队。入队的规则是:先到该行中最高的人的右 -> 左的顺序。
- 如果身高有相同的,那么按照姓名进行排序
2.简单示例
如下给出一行中排队的示例,假设现在有5个人,身高分别是:190, 188, 186, 175, 170
。 那么这五个人入队的顺序如下:
190
=>
188 190
=>
188 190 186
=>
175 188 190 186 170
最后的队形就是: 175, 188, 190, 186, 170
如果遇到有相同身高的人,则按照姓名进行站队。
例如,有如下三个人,其中Eva 和 Ann的身高相同:于是得到的排序应该是Mike=170 ,Ann=168,Eva=168
而不是Mike=170 ,Eva=168,Ann=168
。根据排序得到的站队就是:
Ann=168
Mike=170
Eva=168
而不是:
Eva=168
Mike=170
Ann=168
3.代码
下面给出java 代码
import java.util.*;
public class Main {
private static Map<String, Integer> student = new HashMap<String, Integer>();
private static List<Map.Entry<String, Integer>> lists ;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int totalNumber = in.nextInt();//总人数
int lineNumber = in.nextInt();//每行的人数
in.nextLine();
String line[];
String name;
int height;
for (int i = 0; i < totalNumber; i++) {
line = in.nextLine().trim().split(" ");
name = line[0];
height = Integer.parseInt(line[1]);
student.put(name, height);
}
lists = new ArrayList<Map.Entry<String, Integer>>(student.entrySet());
sort();
//lineNumber 表示的是每行站队的人数
//List<Map.Entry<String, Integer>> rows = new ArrayList<>();
int rowNumber = totalNumber / lineNumber;
//这个result 是用于保存每行的站队人数的姓名
//但是不能用lineNumber 作为数组大小,因为可能会导致数组溢出
String[] result = new String[lineNumber*2];
//==============================================================第一行==============================================
int rest = totalNumber % lineNumber + lineNumber; // 最后一行站队的人数
int position = rest / 2 ; //表示每个人的下标 + 初始化值
result[rest/2] = lists.get(0).getKey(); //最高者的位置
for(int j = 1 ; j < rest ;j += 2) { //从左往右添加
position -= 1; //往前移一个下标
result[position] = lists.get(j).getKey(); //将姓名添加到其中
}
position = rest / 2 ;//reset
for(int j = 2 ; j < rest ;j += 2) { //从左往右添加
position ++;
result[position] = lists.get(j).getKey(); //将姓名添加到其中
}
//每行的站队排好之后 就输出
for(int k = 0;k < result.length;k++) { // invalid null
if (result[k] == null) {
System.out.println();//输出换行
break;
}
if (result[k+1] != null) {
System.out.print(result[k] + " ");
} else {
System.out.print(result[k]);
}
}
int j = 0;
while(j< rest) {
lists.remove(0);//删除前 lineNumber 个元素
j++;
}
//============================== 这个循环是用于找出每行的站队人数 => 但是不包括最后一行==============================================
//因为上面的结果对后面的计算可能有污染,所以需要重置结果
for(int z = 0;z< result.length;z++) {
result[z] = null;
}
for(int i = 0;i < rowNumber - 1 ;i++) {
result[lineNumber/2] = lists.get(0).getKey();
position = lineNumber/2;
for(j = 1;j < lineNumber ;j += 2) { //从左往右添加
position --;
result[position] = lists.get(j).getKey(); //将姓名添加到其中
}
position = lineNumber / 2 ;//reset -> 因为这个是从位置1开始存放
for( j = 2;j < lineNumber ;j += 2) { //从右往左添加
position ++;
result[position] = lists.get(j).getKey(); //将姓名添加到其中
}
//每行的站队排好之后 就输出
for(int k = 0;k < result.length;k++) { // invalid null
if (result[k] == null) {
System.out.println();//输出换行
break;
}
if (result[k+1] != null) {
System.out.print(result[k] + " ");
} else {
System.out.print(result[k]);
}
}
j = 0;
while(j< lineNumber) {
lists.remove(0);//删除前 lineNumber 个元素
j++;
}
}
//根据height and name 排序
public static void sort() {
Collections.sort(lists, new Comparator<Map.Entry<String, Integer>>() {
@Override
public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
int status = o1.getValue().compareTo(o2.getValue()) ;
if (status == 0) {
status = -1 * (o1.getKey().compareTo(o2.getKey())) ;
}
return -1 * status; //降序排序
}
});
}
}
/* 注意这里在John 159之后有一个换行。
10 3
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159
10 3
Tom 188
Mike 170
Eva 168
Tim 158
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159
10 4
Tom 188
Mike 170
Eva 168
Tim 160
Joe 190
Ann 168
Bob 175
Nick 186
Amy 160
John 159
3 3
Tim 160
Amy 160
John 159
3 3
Mike 170
Eva 168
Ann 168
3 3
Mike 170
Eva 170
Ann 168
4 3
Tom 188
Bob 175
Nick 186
Joe 190
*/
但是上述的这个代码不能全部AC,因为会有一部分数据是运行超时的,毕竟这不是C/C++。提交结果如下:
接着修改呗。