일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 백준 14938번 서강그라운드
- ac 5430번
- mysql hy000 에러
- hash
- Java
- map
- kotlin
- StringBuilder
- 백준 1806번 부분합 java
- HashMap
- dp
- 백준 3190번
- 코틀린기초
- 백준 2467번 용액 자바 - 이분탐색
- Stack
- append
- 프로그래머스
- HashSet
- StringTokenizer
- 백준 1647번 도시 분할 계획 - java
- 백준 1197번 최소 스패닝 트리 - java
- 백준 1541
- toUpperCase
- replace()
- 프로그래머스 java
- 18111번 마인크래프트 - java 구현
- 최소 힙 1927
- 백준 1043번 거짓말 - java 분리 집합
- 백준 2473번 세 용액 - java
- 프로그래머스 자바
- Today
- Total
말하는 컴공감자의 텃밭
알고리즘 재활 15일차 - 11723, 1927, 5430번 본문
아 오늘 좀 후딱 풀었네
3문제 50분~
집합
출력되는건 check, toggle인 점만 확인하면 더 쉽게 풀 수 있었을거 같다.
비트마스킹으로 메모리 더 적게도 가능하겠다. 꼭 풀고 생각나
연산자설명 | |
& | 비트 단위 AND 연산 (비트가 모두 1이면 1 반환) |
| | 비트 단위 OR 연산 (비트 중 하나 이상 1이면 1 반환) |
^ | 비트 단위 XOR 연산 (비트가 서로 다르면 1 반환) |
~ | 비트 단위 NOT 연산 (0 -> 1, 1 -> 0 반환) |
<< | 비트 Left Shift 연산 (비트를 왼쪽으로 이동) |
>> | 비트 Right Shift 연산 (비트를 오른쪽으로 이동) |
보니까 또 기억나네
커맨드 별로 기능을 나누어서 작성해주었다.
Set 으로 푼 코드 🔽🔽
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 40 41 42 43 44 45 46 47 48 49 50 | import java.io.*; import java.util.*; public class Main { // 집합 public static int M; public static Set<Integer> set = new HashSet<>(); public static StringBuilder sb = new StringBuilder(); public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); M = Integer.parseInt(br.readLine()); for (int i = 0; i < M; i++) { StringTokenizer st = new StringTokenizer(br.readLine()); String cmd = st.nextToken(); if (cmd.equals("all")) { for (int j = 1; j <= 20; j++) { set.add(j); } } else if (cmd.equals("empty")) { set.clear(); } else { int x = Integer.parseInt(st.nextToken()); switch (cmd) { case "add": set.add(x); break; case "remove": set.remove(x); break; case "check": sb.append(set.contains(x) ? "1\n" : "0\n"); break; case "toggle": if (set.contains(x)) { set.remove(x); } else { set.add(x); } break; } } } System.out.print(sb.toString()); } } | cs |
비트마스킹으로 푼 코드 🔽🔽
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 40 41 42 43 | import java.io.*; import java.util.*; public class Main { // 집합 - 비트마스킹 public static int M; public static int bitSet = 0; public static StringBuilder sb = new StringBuilder(); public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); M = Integer.parseInt(br.readLine()); for (int i = 0; i < M; i++) { StringTokenizer st = new StringTokenizer(br.readLine()); String cmd = st.nextToken(); if (cmd.equals("all")) { bitSet = (1 << 20) - 1; } else if (cmd.equals("empty")) { bitSet = 0; } else { int x = Integer.parseInt(st.nextToken()) - 1; // 19까지 사용 switch (cmd) { case "add": bitSet |= (1 << x); break; case "remove": bitSet &= ~(1 << x); break; case "check": sb.append((bitSet & (1 << x)) != 0 ? "1\n" : "0\n"); break; case "toggle": bitSet ^= (1 << x); break; } } } System.out.print(sb.toString()); } } | cs |
이상하게 별로 차이 안나네..
두 코드를 비교하면 이정도로 차이가 난다.
효율 비교 | HashSet 사용 코드 | 비트마스킹 사용 코드 |
메모리 사용량 | 높음 (각 원소마다 객체 오버헤드 발생) | 낮음 (4바이트 고정) |
시간 복잡도 | 평균 O(1), 최악 O(n) | O(1) |
연산 속도 | 상대적으로 느림 | 매우 빠름 |
코드 복잡도 | 상대적으로 간단 | 조금 더 복잡 (비트 연산 이해 필요) |
모쪼록~ 비트마스킹을 알고리즘에서는 처음 써본것 같다.
난이도 올려서도 풀어봐야지
최소 힙
0이 입력되면 현재까지 넣은 값중에서 가장 작은 값을 출력하면 되는 문제이다.
당연히 정렬을 계속하면서 출력하면 메모리 손해가 크므로 정렬된 큐인 우선순위 큐를 활용해 주었다.
우선순위 큐는 힙으로 구현되고 힙은 완전 이진트리 형태이다.
O(log₂n) 의 시간 복잡도를 가지므로 삽입, 삭제에도 용이.
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 | import java.io.*; import java.util.*; public class Main { // 최소 힙 public static int N; public static Set<Integer> set = new HashSet<>(); public static StringBuilder sb = new StringBuilder(); public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); N = Integer.parseInt(br.readLine()); PriorityQueue<Integer> Pq = new PriorityQueue<>(); for (int i = 0; i < N; i++) { StringTokenizer st = new StringTokenizer(br.readLine()); int now = Integer.parseInt(st.nextToken()); if(now == 0){ if(Pq.isEmpty()){ sb.append("0").append("\n"); }else{ sb.append(Pq.poll()).append("\n"); } }else{ Pq.add(now); } } System.out.print(sb.toString()); } } | cs |
자주 보는거 같구나 호호
AC
R 또는 D의 커맨드가 들어오고, 숫자 배열이 주어진다.
R은 배열 뒤집기 ex) 1,2,3 -> 3,2,1
D는 Delete로 맨 앞 지워주는 커맨드이다.
모든 함수를 동작하고 남은 결과를 출력해주면 된다.
배열을 계속해서 R을 만날때마다 뒤집는건 비효율적이다.
따라서 양방향인 Deque을 사용해서 문제를 해결해줬다.
position이 정방향이면 앞에서 연산하고, 역방향이면 뒤에서 연산해주었다.
error의 경우 큐가 비어있음에도 D 입력이 들어오는 경우를 신경써주면 된다.
에러 발생 시 error를 StringBuilder에 넣어주고 for문을 탈출하게 해줬다.
배열이 존재하면 괄호로 덮어줘야하고, 출력의 경우 큐에 숫자가 남아있을때만 ',' 를 출력해주었다.
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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | import java.io.*; import java.util.*; public class Main { // AC public static int T; public static StringBuilder sb = new StringBuilder(); public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; T = Integer.parseInt(br.readLine()); for (int i = 0; i < T; i++) { boolean position = false; // false == 정방향, true == 역방향 boolean error = false; String cmd = br.readLine(); int N = Integer.parseInt(br.readLine()); Deque<Integer> deque = new ArrayDeque<>(); st = new StringTokenizer(br.readLine(), ",[]"); while (st.hasMoreTokens()) { deque.offer(Integer.parseInt(st.nextToken())); } for (char c : cmd.toCharArray()) { if (c == 'R') { position = !position; } else if (c == 'D') { if (deque.isEmpty()) { sb.append("error\n"); error = true; break; } if (position) { deque.pollLast(); } else { deque.pollFirst(); } } } if (!error) { sb.append("["); while (!deque.isEmpty()) { sb.append(position ? deque.pollLast() : deque.pollFirst()); if (!deque.isEmpty()) { sb.append(","); } } sb.append("]\n"); } } System.out.print(sb.toString()); } } | cs |
'알고리즘 > Backjoon - Java' 카테고리의 다른 글
백준 1647번 도시 분할 계획 - Java 최소 스패닝 트리 (0) | 2024.08.26 |
---|---|
백준 1806번 부분합 - Java 투 포인터 (0) | 2024.08.21 |
알고리즘 재활치료 14일차 - 10816, 15666, 1504번 (0) | 2024.08.16 |
알고리즘 재활 13일차 - 15663, 1149, 1753번 (0) | 2024.08.15 |
알고리즘 재활 12일차 - 백준 2869, 15654, 16236번 (0) | 2024.08.14 |