https://www.acmicpc.net/problem/9375
9375번: 패션왕 신해빈
첫 번째 테스트 케이스는 headgear에 해당하는 의상이 hat, turban이며 eyewear에 해당하는 의상이 sunglasses이므로 (hat), (turban), (sunglasses), (hat,sunglasses), (turban,sunglasses)로 총 5가지 이다.
www.acmicpc.net
코드설명
HashMap + 경우의 수에 대한 이해 문제입니다.
처음에 풀었을떄는 각 경우에 대한 조합을 만들었습니다.
즉, 1개로 이루어진 조합, 2개로 이루어진 조합, 3개로 이루어진 조합 ... 을 만든뒤에
각 경우에서 만들어질 수 있는 경우의 수를 모두 더했습니다.
하지만 시간초과가 발생합니다.
먼저 왜 시간초과가 발생하는지 알아봅니다.
테스트케이스 T는 100입니다.
해빈이가 가진 의상의 수는 최대 30개입니다.
현재 시간복잡도는,
입력처리에는 O(TN).
조합계산에는 O(2^N) 입니다.(선택할지 말지 2가지 경우의 수를 N번 반복합니다.)
N = 30 이므로 2^30(1073741824) 이므로, 문제에서 주어진 1초 안에는 미세한 차이로 불가합니다.
더 좋은 방식이 있습니다.
문제에서는 "옷을 입지 않는 경우"를 구해야만 합니다.
그렇다면, 옷을 입지 않는 경우 1개를 각 옷의 종류에 한개씩 추가합니다.
그리고 마지막에 옷을 입지 않는 경우가 모든 옷의 종류에서 선택되는 경우인 1 가지를 뺴주면됩니다.
이렇게 문제를 풀 수 있는 방법을 생각해야한다는점에서 좋은 문제인 것 같습니다.
코드
package algorhythm; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map.Entry; import java.util.StringTokenizer; public class Main { public static int N, C, T; public static HashMap<String, Integer> hashmap = new HashMap<>(); public static int answer = 0; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); T = Integer.parseInt(st.nextToken()); while(T-- > 0) { hashmap = new HashMap<>(); st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); for(int i=0;i<N;i++) { st = new StringTokenizer(br.readLine()); String a = st.nextToken(); String b = st.nextToken(); hashmap.put(b, hashmap.getOrDefault(b, 0) + 1); } answer = 1; //만약 들어온 옷의 종류가 1개라면, 각각의 개수만 더해집니다. for(Entry<String, Integer> entrySet : hashmap.entrySet()) { answer *= (entrySet.getValue() + 1); } answer -= 1; System.out.println(answer); } } }
package Main; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; public class Main { public static int N, T, M; public static int answer = 0; public static int[] cache; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); T = Integer.parseInt(st.nextToken()); cache = new int[11]; Arrays.fill(cache, -1); while(T-- > 0) { st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); HashMap<String, Integer> hashmap = new HashMap<>(); for(int i=0;i<N;i++) { st = new StringTokenizer(br.readLine()); String clothName = st.nextToken(); String clothKind = st.nextToken(); hashmap.put(clothKind, hashmap.getOrDefault(clothKind, 0) + 1); } answer = 1; for(Map.Entry<String, Integer> entrySet : hashmap.entrySet()){ answer = answer * (entrySet.getValue() + 1); } answer -= 1; System.out.println(answer); } } }
모든 조합마다의 각 시간을 모두 연산합니다. 시간복잡도(2^N)
그렇기에, 시간초과가 나는 코드입니다.
package algorhythm; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.HashMap; import java.util.Map.Entry; import java.util.StringTokenizer; public class Main { public static int N, C, T; public static HashMap<String, Integer> hashmap = new HashMap<>(); public static StringBuilder sb = new StringBuilder(); public static int answer = 0; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); T = Integer.parseInt(st.nextToken()); while(T-- > 0) { hashmap = new HashMap<>(); st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); for(int i=0;i<N;i++) { st = new StringTokenizer(br.readLine()); String a = st.nextToken(); String b = st.nextToken(); hashmap.put(b, hashmap.getOrDefault(b, 0) + 1); } answer = 0; int size = hashmap.keySet().size(); int[] value = new int[size]; int index = 0; //만약 들어온 옷의 종류가 1개라면, 각각의 개수만 더해집니다. for(Entry<String, Integer> entrySet : hashmap.entrySet()) { value[index++] = entrySet.getValue(); } for(int i=1; i<=size;i++) { //combination (1), combination(2) .. 가 실행됨. //그러면 1 일때 3. 2일때 2개. 로 5가 나와야함. combination(0, 0, i, value, new int[i]); } sb.append(answer); } System.out.println(sb.toString()); } public static void combination(int level, int idx, int maxSize, int[] value, int[] selected) { if(level == maxSize) { //원하는 숫자만큼 정해졌다면, 해당 내에서 나올 수 있는 개수를 구합니다. int temp = 1; for(int i=0;i<selected.length;i++) { temp *= value[selected[i]]; } answer += temp; return ; } for(int i=idx;i<value.length;i++) { selected[level] = i; combination(level + 1, i + 1, maxSize, value, selected); selected[level] = -1; } } }
'알고리즘 > 해시를 사용한 집합과 맵' 카테고리의 다른 글
[백준] 4358 생태학 - HashMap(해시맵) + TreeMap(트리맵) + 소수점(printf, .4f, format) JAVA (0) | 2024.04.01 |
---|---|
[백준] 13414 수강신청 - LinkedHashSet(해시셋) JAVA (0) | 2024.04.01 |
[백준] 2910 빈도 정렬 - LinkedHashMap(링크드해시맵) + LinkedHashSet(링크드해시셋) + Comparable JAVA (0) | 2024.03.28 |
[백준] 26069 붙임성 좋은 총총이 - HashSet(해시셋) JAVA (0) | 2024.03.28 |
[백준] 25192 인사성 밝은 곰곰이 - HashSet(해시셋) JAVA (0) | 2024.03.26 |