https://www.acmicpc.net/problem/18248
18248번: 제야의 종
첫 줄에 N(1 ≤ N ≤ 1,000)과 M(1 ≤ M ≤ 100)이 주어진다. i+1(1 ≤ i ≤ N)번째 줄에는 M개의 정수 ai,1, ai,2, ..., ai,M 이 주어지는데, ai,j가 1이면 사람 i가 j 번째 타종을 들었음을 의미하고, 0이면 듣
www.acmicpc.net
상당히 재밌는 문제였습니다.
얼핏보면 이게 뭔소리지 싶은 문제일 수도 있습니다.
하지만 소리가 발생한 지점으로부터 원형으로 퍼져나간다는 사실을 생각해보면 쉽게 풀이방법을 알아 낼 수 있습니다.
주어진 예제가 너무 단편적이니 제가 직접 예제를 만들어 보겠습니다.
10 5
1 0 1 0 1
0 0 0 0 0
0 0 1 0 0
1 0 1 0 1
1 0 1 0 0
0 0 1 0 0
1 0 1 0 0
0 0 0 0 0
1 0 1 1 1
0 0 1 0 0
조건에 성립하는 예제라고 가정하고, 이 예제를 시각적으로 나타내 볼까요?
네, 그림을 보고 슬슬 느끼셨을것 같은데요.
이 문제는 정렬 문제입니다.
소리가 원형으로 퍼지기 때문에 바깥 사람이 들은 종소리를 더 가까운 사람은 무조건 들을 수 밖에 없죠.
따라서 종소리를 들은 숫자대로 사람들을 내림차순으로 정렬한다면,
안의 사람이 듣지 못한 종소리를 더 바깥에 있는 사람이 듣는 일은 없습니다.
(안의 사람이 들은 종소리를 바깥사람이 못듣는 경우는 당연히 존재합니다.)
예시를 살짝 바꿔 볼까요??
10 5
1 0 1 0 1
0 0 0 0 0
0 0 1 0 0
1 0 1 0 1
1 0 1 0 0
0 0 1 0 0
1 0 1 0 0
0 1 0 0 0
1 0 1 1 1
0 0 1 0 0
만약 바꾼 예시처럼 8번 사람이 아무도 듣지 못한 2번 종소리를 들었다고 가정해 봅시다.
그럼 8번은 다른 모두보다 종에 가까이 있어야 하는데, 그렇다면 다른 종소리도 자연스럽게 듣게 됩니다.
옳바른 예시와 잘못된 예시를 정렬 해보면 이렇게 되겠네요.
옳은 예
10 5
1 0 1 1 1
1 0 1 0 1
1 0 1 0 1
1 0 1 0 0
1 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 0 0 0
0 0 0 0 0
틀린 예
10 5
1 0 1 1 1
1 0 1 0 1
1 0 1 0 1
1 0 1 0 0
1 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 0 1 0 0
0 1 0 0 0
0 0 0 0 0
모순관계가 생기면 문제에서 주어진 예시 2번 처럼 어떻게든 0->1로 바뀌는 모습이 나타날 수 밖에 없습니다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;
public class Main {
static StringTokenizer st;
public static void main(String[] args) throws NumberFormatException, IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
st = new StringTokenizer(br.readLine());
int N = Integer.parseInt(st.nextToken());
int M = Integer.parseInt(st.nextToken());
int[][] people = new int[N][M + 1];
for (int n = 0; n < N; n++) {
st = new StringTokenizer(br.readLine());
int sum = 0;
for (int m = 0; m < M; m++) {
people[n][m] = Integer.parseInt(st.nextToken());
sum += people[n][m];
}
people[n][M] = sum;
}
Arrays.sort(people, (e1, e2) -> {
return e2[M] - e1[M];
});
boolean answer = true;
loop: for (int m = 0; m < M; m++) {
int check = people[0][m];
for (int n = 0; n < N; n++) {
if(check < people[n][m]) {
answer = false;
break loop;
}
check = people[n][m];
}
}
if (answer) {
System.out.println("YES");
} else {
System.out.println("NO");
}
}
}
'🔍 알고리즘 > 백준 Java' 카테고리의 다른 글
[Java] 백준 2166번. 다각형의 면적 (골드5) (0) | 2021.12.02 |
---|---|
[Java] 백준 14939번. 불끄기 (플래티넘5) (0) | 2021.12.02 |
[JAVA] 백준 4600번. 정글의법칙 (실버2) (0) | 2021.11.30 |
[JAVA] 백준 2565번. 전깃줄 (실버1) (0) | 2021.11.30 |
[JAVA] 백준 1958번. LCS 3 (골드3) (0) | 2021.11.29 |