14569번 시간표 짜기
🅰 설계
1. 어떤 방법을 사용할 것인가?
- BruteForce
모든 과목의 수업 시간을 하나씩 체크하면서 그 시간이 비는지 체크한다. 이 경우 O(N*k*M) = O(500,000,000)으로 시간 제한을 넘긴다. 다른 방법이 필요하다. - BitMask
결국 어떤 과목과 학생의 시간을 탐색하는 방법의 최적화가 필요하다.
시간이 150 사이의 주어지는 시간의 Bit를 켜두고 &연산자를 활용하면 50번의 비교를 1번의 비교로 줄일 수 있다.50 사이로 주어지므로, 64Bit 자료형을 사용하여 1
2. BitMask 코드
1
2
3
4
5
6
7
8
9
|
N = Integer.parseInt(br.readLine());
long[] lectures = new long[N];
for(int i=0;i<N;i++){
st = new StringTokenizer(br.readLine());
k = Integer.parseInt(st.nextToken());
for(int j=0;j<k;j++){
lectures[i] |= 1L << Long.parseLong(st.nextToken());
}
}
|
cs |
수업의 개수만큼 1~50의 시간을 lecutres[j]
에 Bit를 켠다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
for(int i=0;i<M;i++){
st = new StringTokenizer(br.readLine());
k = Integer.parseInt(st.nextToken());
long student = 0;
int subans = 0;
for(int j=0;j<k;j++){
student |= 1L << Long.parseLong(st.nextToken());
}
for(int j=0;j<N;j++){
if((student & lectures[j]) == lectures[j]){
subans++;
}
}
sb.append(subans).append("\n");
}
|
cs |
학생의 개수만큼 다시 똑같이 1~50의 시간을 student
에 Bit를 켠다.
그리고 앞서 Bit를 켜 뒀던 수업들을 &
연산으로 비교하여 lecture[j]
가 그대로 남는다면 그 수업시간은 학생이 모두 가능하다는 뜻이 된다.
3. 전체 코드
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
import java.io.*;
import java.util.*;
public class Main {
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StringTokenizer st;
static int N,M,k;
public static void main(String[] args) throws IOException{
N = Integer.parseInt(br.readLine());
long[] lectures = new long[N];
for(int i=0;i<N;i++){
st = new StringTokenizer(br.readLine());
k = Integer.parseInt(st.nextToken());
for(int j=0;j<k;j++){
lectures[i] |= 1L << Long.parseLong(st.nextToken());
}
}
M = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();
for(int i=0;i<M;i++){
st = new StringTokenizer(br.readLine());
k = Integer.parseInt(st.nextToken());
long student = 0;
int subans = 0;
for(int j=0;j<k;j++){
student |= 1L << Long.parseLong(st.nextToken());
}
for(int j=0;j<N;j++){
if((student & lectures[j]) == lectures[j]){
subans++;
}
}
sb.append(subans).append("\n");
}
System.out.print(sb.toString());
}
}
|
cs |
✅ 후기
BruteForce로 시간 제한안에 풀지 못한다고 생각했을 때 비교연산을 줄이는 방법으로 BitMask를 쓰는 것이 상당히 재밌는 문제였다.
'Problem Solving > Baekjoon' 카테고리의 다른 글
[ACMICPC] 14938 . 서강 그라운드 (0) | 2021.08.08 |
---|---|
[ACMICPC] 10250 . ACM 호텔 (0) | 2021.08.07 |
[ACMICPC] 18111 . 마인크래프트 (0) | 2021.08.05 |
[ACMICPC] 2468 . 안전 영역 (0) | 2021.08.04 |
[ACMICPC] 2470 . 두 용액 (0) | 2021.08.03 |