T2135
某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前 5 名学生发奖学金。期末,每个学生都有 3 门课的成绩:语文、数学、英语。先按总分从高到低排序,如果两个同学总分相同,再按语文成绩从高到低排序,如果两个同学总分和语文成绩都相同,那么规定学号小的同学排在前面,这样,每个学生的排序是唯一确定的
解析:构造 Student 类,用来记录学生数据,设立五个私有数据,ID,Yscore,Msocre,Escore,totalScore,通过构造器进行赋值
在主类 T2135 中,构造 Student 类 的ArrayList 对象来存储数据,并使用 Comparator 比较器进行比较
注意:Comparator 比较器默认整数排序从小到大
@Test
public void testComparator(){
ArrayList<Integer> list = new ArrayList();
list.add(2);
list.add(5);
list.add(10);
list.add(6);
list.add(1);
//默认整数排序从小到大
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;
}
});
for (Integer integer : list) {
System.out.println(integer);
}
}
package com.java3.ch6;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
public class T2135 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
ArrayList<Student> list = new ArrayList<>();
for (int i = 0; i < n; i++) {
int Yscore = scan.nextInt();
int Mscore = scan.nextInt();
int Escore = scan.nextInt();
int total = Yscore + Mscore + Escore;
Student stu = new Student(i+1,Yscore,Mscore,Escore,total);
list.add(stu);
}
Collections.sort(list, new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
if((o1.getTotalScore() == o2.getTotalScore()) &&(
o1.getYscore() == o2.getYscore())){
return o1.getID()-o2.getID();
}else if(o1.getTotalScore() == o2.getTotalScore()){
return -(o1.getYscore() - o2.getYscore());
}else{
return -(o1.getTotalScore() - o2.getTotalScore());
}
}
});
// for (Student student : list) {
// System.out.println(student.getID() + " " + student.getTotalScore());
// }
for (int i = 0; i < 5; i++) {
Student stu = list.get(i);
System.out.println(stu.getID() + " " + stu.getTotalScore());
}
}
}
class Student {
private int ID;
private int Yscore;
private int Msocre;
private int Escore;
private int totalScore;
public Student(int ID, int yscore, int msocre, int escore, int totalScore) {
this.ID = ID;
Yscore = yscore;
Msocre = msocre;
Escore = escore;
this.totalScore = totalScore;
}
public int getID() {
return ID;
}
public int getYscore() {
return Yscore;
}
public int getMsocre() {
return Msocre;
}
public int getEscore() {
return Escore;
}
public int getTotalScore() {
return totalScore;
}
@Override
public String toString() {
return "Student{" +
"ID=" + ID +
", Yscore=" + Yscore +
", Msocre=" + Msocre +
", Escore=" + Escore +
", totalScore=" + totalScore +
'}';
}
}
8
80 89 89
88 98 78
90 67 80
87 66 91
78 89 91
88 99 77
67 89 64
78 89 98
8 265
2 264
6 264
1 258
5 258
T1429
蒜头君的电脑里面有一些歌。现在他需要把这些歌装进一个硬盘里面。
硬盘大小有限,由于蒜头君下载的都是无损版本,每首歌的占用空间比较大,硬盘不一定装得下,然后他需要压缩其中的一部分歌曲这样他才能将尽可能多的歌曲装进他的硬盘里。
但是他想尽量压缩的歌曲数量尽量少,他不知道该怎么做,就来找你帮忙了。
解析:先处理特殊情况,磁盘容量 大于 原始歌曲容量 ,不需要压缩歌曲,输出 0,磁盘容量 小于 压缩歌曲容量 ,无法存储,输出 -1,一般情况,使用 countSong 记录需要压缩歌曲的数量,使用 ArrayList 存储歌曲列表,并按照差值 (原始容量 - 压缩容量) 进行排序
尽量压缩的歌曲数量尽量少:策略,先存储差值大的,在储存差值小的
package com.java3.ch7;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
public class T1429{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int songAmount = scan.nextInt();
int diskCapacity = scan.nextInt();
ArrayList<Song> list = new ArrayList<>();
for (int i = 0; i < songAmount; i++) {
int originalValue = scan.nextInt();
int nowValue = scan.nextInt();
Song song = new Song(originalValue,nowValue,originalValue - nowValue);
list.add(song);
}
Collections.sort(list, new Comparator<Song>() {
@Override
public int compare(Song o1, Song o2) {
//按照差值从大到小排序
return -(o1.getDifference() - o2.getDifference());
}
});
int totalOriginalValue = 0;
int totalNewValue = 0;
for (Song song : list) {
totalOriginalValue += song.getOriginalValue();
totalNewValue += song.getNowValue();
}
if(diskCapacity > totalOriginalValue){
System.out.println("0");
return;
}else if(diskCapacity < totalNewValue){
System.out.println("-1");
return;
}
int countSong = 1;
while(true){
int tempValue = 0;
for (int i = 0; i < list.size(); i++) {
Song song = list.get(i);
if(i < countSong){
tempValue += song.getNowValue();
}else{
tempValue += song.getOriginalValue();
}
}
if(diskCapacity >= tempValue){
System.out.println(countSong);
break;
}
countSong++;
}
}
}
class Song {
private int originalValue;
private int nowValue;
private int difference;
public Song(int originalValue, int nowValue, int difference) {
this.originalValue = originalValue;
this.nowValue = nowValue;
this.difference = difference;
}
public int getOriginalValue() {
return originalValue;
}
public int getNowValue() {
return nowValue;
}
public int getDifference() {
return difference;
}
}
4 21
10 8
7 4
3 1
5 4
2
T1133
给定 n×n 由 0 和 1 组成的矩阵,如果矩阵的每一行和每一列的 1 的数量都是偶数,则认为符合条件。
你的任务就是检测矩阵是否符合条件,或者在仅改变一个矩阵元素的情况下能否符合条件。
“改变矩阵元素”的操作定义为 0 变成 1 或者 1变成 0。
解析:使用 Martix 类来,attr 属性 (row or line),total 1的数量,index 索引值,统计行数和列数中1的个数是否为偶数,然后根据不同的情况进行输出
package com.java3.ch7;
import java.util.ArrayList;
import java.util.Scanner;
public class T1133{
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int[][] array = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
array[i][j] = scan.nextInt();
}
}
ArrayList<Martix> list = new ArrayList<>();
//记录行数据
for (int i = 0; i < n; i++) {
int tempRow = 0;
for (int j = 0; j < n; j++) {
tempRow += array[i][j];
}
Martix martix = new Martix("row",tempRow,i + 1);
list.add(martix);
}
//记录列数据
for (int i = 0; i < n; i++) {
int tempLine = 0;
for (int j = 0; j < n; j++) {
tempLine += array[j][i];
}
Martix martix = new Martix("line",tempLine,i + 1);
list.add(martix);
}
//统计行数和列数中1的个数是否为偶数
int rows = 0;
int indexRow = 0;
int lines = 0;
int indexLine = 0;
for (Martix martix : list) {
if("row".equals(martix.getAttr())){
if(martix.getTotal() % 2 == 1){
rows++;
indexRow = martix.getIndex();
}
}else if("line".equals(martix.getAttr())){
if(martix.getTotal() % 2 == 1){
lines++;
indexLine = martix.getIndex();
}
}
}
//输出
if(rows == 0 && lines == 0){
System.out.println("OK");
}else if(rows == 1 && lines == 1){
System.out.println(indexRow + " " + indexLine);
}else{
System.out.println("Corrupt");
}
}
}
class Martix {
private String attr;
private int total;
private int index;
public Martix(String attr, int total, int index) {
this.attr = attr;
this.total = total;
this.index = index;
}
public String getAttr() {
return attr;
}
public int getTotal() {
return total;
}
public int getIndex() {
return index;
}
}
4
1 0 1 0
0 0 1 0
1 1 1 1
0 1 0 1
2 3
T1246
现在有一些长度相等的 DNA 串(只由 ACGT 四个字母组成),请将它们按照逆序对的数量多少排序。
逆序对指的是字符串A中的两个字符 A[i]、A[j],具有 i < j 且 A[i] > A[j] 的性质。如字符串 “ATCG” 中,T 和 C 是一个逆序对,T 和 G 是另一个逆序对,这个字符串的逆序对数为 2。
解析:使用 calculateCount() 方法计算每个字符串中的逆序对数量,使用 Comparator() 比较器 进行排序,总结起来就是流畅 ,舒服
package com.java3.ch7;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Scanner;
public class T1246 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int strLength = scan.nextInt();
int strCount = scan.nextInt();
ArrayList<String> list = new ArrayList<>();
for (int i = 0; i < strCount; i++) {
list.add(scan.next());
}
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return calculateCount(o1) - calculateCount(o2);
}
});
for (String s : list) {
System.out.println(s);
}
}
public static int calculateCount(String str){
int count = 0;
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
for (int j = i + 1; j < chars.length; j++) {
if(chars[i] > chars[j]){
count++;
}
}
}
return count;
}
}
10 6
AACATGAAGG
TTTTGGCCAA
TTTGGCCAAA
GATCAGATTT
CCCGGGGGGA
ATCGATGCAT
CCCGGGGGGA
AACATGAAGG
GATCAGATTT
ATCGATGCAT
TTTTGGCCAA
TTTGGCCAAA