백준 2817 ALPS식 투표 (JAVA 자바 풀이)
전혀 어렵게 풀 문제가 아니었는데 문제를 잘못 읽어서 한참을 헤맸다.
제대로 안 읽은 부분을 밑줄 쳐보면 다음과 같다.
1) 전체 대회 참가자의 5% 미만을 걸러야 하는 조건
참가자가 투표를 하지 않을 수도 있다는 것만 보고 총 투표수를 받아야 되나 생각했다. 어떻게 할까를 고민하다가 그냥 한 번에 받는 방법이 제일 간단해 보여서 이렇게 짰었다.
List<Staff> staffs = new ArrayList<>();
List<Double> scores = new ArrayList<>();
Map<String, Integer> staffInformation = new LinkedHashMap<>();
while (staffCounts--> 0) {
StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine());
String name = stringTokenizer.nextToken();
int votes = Integer.parseInt(stringTokenizer.nextToken());
staffInformation.put(name, votes);
}
for (Map.Entry<String, Integer> stringIntegerEntry : staffInformation.entrySet()) {
String name = stringIntegerEntry.getKey();
Integer votes = stringIntegerEntry.getValue();
if(votes < participants * 0.05){
continue;
}
Staff staff = Staff.of(name, votes);
staffs.add(staff);
scores.addAll(staff.getScores());
}
먼저 입력값을 다 받아놓고 총 투표수를 계산한 다음 그거로 5% 미만 값을 필터링 하는 방식이다.
계속 틀려서 알고 봤더니 총 투표한 수의 5%가 아니라 전체 참가자 수의 5%이다.
즉, 다음과 같이 맨 처음 받은 staffCounts만으로도 충분했던 것이다.
int participants = Integer.parseInt(bufferedReader.readLine());
int staffCounts = Integer.parseInt(bufferedReader.readLine());
예제 입력 3번 케이스의 경우 총 참가자 수는 206278인데 투표수는 177925이다. 이처럼 다르게 값이 주어지는 경우가 있기 때문에 값을 잘못 계산하면 통과하지 못하는 테스트들이 생긴다.
206278
5
D 44687
A 68188
C 7008
B 48377
G 9665
2) 점수는 실수로 계산되어야 한다는 것
1부터 14까지 나누어 계산되는 값이 정수가 아니라 실수였다. 정수로 계산하면 겹치는 경우가 생긴다. 이 경우 다음과 같은 코드에서 여러 개를 고르게 되기 때문에 문제가 생긴다.
for (int i = 0; i < 14; i++) {
Double score = scores.get(i);
staffs.stream().filter(staff -> staff.isOwn(score))
.forEach(Staff::receiveChip);
}
public boolean isOwn(Double thatScore) {
return scores.stream().anyMatch(score -> score.equals(thatScore));
}
3) 5% 이상의 투표수를 받은 경우 칩이 0이라도 출력해야 한다.
문제 조건에서 5% 이상인 스태프에 대해 칩의 개수를 출력하라고 했기 때문에 전부 출력해주어야 한다.
예를 들어 다음과 같은 테스트 셋의 경우
100
6
A 20
B 19
C 18
D 17
E 16
F 5
이렇게 답이 나와야 한다.
괜히 0을 출력 안하려고
staffs.stream().filter(staff -> staff.getChipCounts() !=0).forEach(System.out::println);
이렇게 필터 조건을 걸어서 또 틀렸다. 다음과 같이 그냥 출력하면 된다.
staffs.forEach(System.out::println);
💡 코드 구현
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.StringTokenizer;
public class Main {
private static final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
public static void main(String[] args) throws IOException {
int participants = Integer.parseInt(bufferedReader.readLine());
int staffCounts = Integer.parseInt(bufferedReader.readLine());
List<Staff> staffs = new ArrayList<>();
List<Double> scores = new ArrayList<>();
while (staffCounts-- > 0) {
StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine());
String name = stringTokenizer.nextToken();
int votes = Integer.parseInt(stringTokenizer.nextToken());
if (votes < participants * 0.05) {
continue;
}
Staff staff = Staff.of(name, votes);
staffs.add(staff);
scores.addAll(staff.getScores());
}
staffs.sort(Staff::compareTo);
scores.sort(Comparator.comparingDouble(Double::doubleValue).reversed());
for (int i = 0; i < 14; i++) {
Double score = scores.get(i);
staffs.stream().filter(staff -> staff.isOwn(score))
.forEach(Staff::receiveChip);
}
staffs.forEach(System.out::println);
}
static class Staff implements Comparable<Staff> {
private String name;
private int votes;
private List<Double> scores;
private int chipCounts;
public Staff(String name, int votes, List<Double> scores) {
this.name = name;
this.votes = votes;
this.scores = scores;
}
public static Staff of(String name, int votes) {
List<Double> list = new ArrayList<>();
for (int i = 1; i <= 14; i++) {
list.add((double)votes / i);
}
return new Staff(name, votes, list);
}
public boolean isOwn(Double thatScore) {
return scores.stream().anyMatch(score -> score.equals(thatScore));
}
public List<Double> getScores() {
return scores;
}
@Override
public String toString() {
return name + " " + chipCounts;
}
public void receiveChip() {
chipCounts++;
}
public String getName() {
return name;
}
@Override
public int compareTo(Staff that) {
return this.name.compareTo(that.getName());
}
}
}
'알고리즘 > 백준' 카테고리의 다른 글
백준 7785 회사에 있는 사람 (JAVA 자바 풀이) (0) | 2023.06.25 |
---|---|
백준 1181 단어 정렬 (JAVA 자바 풀이) | 문자열 길이순, 알파벳 순 정렬, 스트링 compareTo 메서드, thenComparing 메서드 (0) | 2023.06.25 |
백준 2840 행운의 바퀴 (JAVA 자바 풀이) (0) | 2023.06.24 |
백준 1730 판화 (JAVA 자바 풀이) (0) | 2023.06.09 |
백준 11068 회문인 수 (JAVA 자바 풀이) (0) | 2023.06.09 |