728x90
https://www.acmicpc.net/problem/11723
11723번: 집합
첫째 줄에 수행해야 하는 연산의 수 M (1 ≤ M ≤ 3,000,000)이 주어진다. 둘째 줄부터 M개의 줄에 수행해야 하는 연산이 한 줄에 하나씩 주어진다.
www.acmicpc.net
풀이)
- 풀이1 -
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
public class Main_BJ_11723_집합 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int m = Integer.parseInt(br.readLine());
StringTokenizer st;
HashMap<Integer, Integer> map = new HashMap<>();
for(int i=0; i<m; i++){
st = new StringTokenizer(br.readLine());
String command = st.nextToken();
if(command.equals("all")){
for(int j=0; j<21; j++){
map.put(j, 1);
}
}else if(command.equals("empty")){
map.clear();
}else{
int num = Integer.parseInt(st.nextToken());
switch (command){
case "add":
if(!map.containsKey(num))
map.put(num, 1);
break;
case "remove":
map.remove(num);
break;
case "check":
if(map.containsKey(num))
sb.append("1\n");
else
sb.append("0\n");
break;
case "toggle":
if(map.containsKey(num))
map.remove(num);
else
map.put(num, 1);
break;
}//switch
}
}//for
System.out.println(sb);
}//main
}
만약, StringBuilder를 사용하지 않고, System.out.println을 사용한다면 시간초과를 볼 것이다!!
하지만 문제 자체가 비트마스크이므로, 한 번 찾아보았다.
- 비트마스킹을 활용한 풀이 -
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
public class Main_BJ_11723_집합2 {
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int m = Integer.parseInt(br.readLine());
int bit = 0;
StringTokenizer st;
for(int i=0; i<m; i++){
st = new StringTokenizer(br.readLine());
String command = st.nextToken();
int num;
switch (command){
case "add":
num = Integer.parseInt(st.nextToken());
//num-1 => 최대 20이기 때문에 0~19까지 자리수로 표현하기 때문.
bit |= (1 << (num-1));
break;
case "remove":
num = Integer.parseInt(st.nextToken());
bit &= ~(1 << (num-1));
break;
case "check":
num = Integer.parseInt(st.nextToken());
sb.append((bit & (1<<(num-1))) != 0 ? "1\n" : "0\n");
break;
case "toggle":
num = Integer.parseInt(st.nextToken());
bit ^= (1 << (num-1));
break;
case "all":
// bit |= (~0);
//21을 shift한 후 1을 빼면 모두 1~20까지 shift한 효과가 있다
bit = (1 << 21) - 1;
break;
case "empty":
bit &= 0;
break;
}//switch
}
System.out.println(sb);
}//main
}
<BitMasking 이론>
비트마스킹
정수를 이진수로 표현하기 위해 쓰는 기법
빠른 수행 시간, 간결한 코드, 더 적은 메모리 사용을 할 수 있다.
비트 연산자
- &
- AND 연산
- |
- OR 연산
- ^
- XOR 연산
- ~
- NOT 연산
- <<
- 왼쪽 shift 연산
- a << b : a를 b만큼 왼쪽으로 시프트
- 1 << 2 == 100(2) => 4
- >>
- 오른쪽 shift 연산
- a >> b : a를 b만큼 오른쪽으로 시프트
- 4 >> 2 == 1(2) => 1
비트마스킹을 이용하면 기깔나게 잘 풀리는 문제들이 몇몇 있었는데, 다시 기억해보는 계기가 되었다
728x90
'코테 > 백준' 카테고리의 다른 글
백준 16928 뱀과 사다리 게임(JAVA) (1) | 2023.01.23 |
---|---|
백준 18870 좌표 압축(JAVA) (0) | 2023.01.22 |
백준 1764 듣보잡(JAVA) (0) | 2023.01.21 |
백준 11399 ATM(JAVA) (0) | 2023.01.20 |
백준 2630 색종이 만들기(JAVA) (0) | 2023.01.19 |