![[SWEA] 3234 준환이의 양팔저울 [SWEA] 3234 준환이의 양팔저울](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
1. 문제
SW Expert Academy
SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!...
swexpertacademy.com
무게 추를 올릴 때 오른쪽 위에 올라가 있는 무게의 총합이 왼쪽에 올라가 있는 무게의 총합보다 더 커져서는 안 된다.
준환이가 양팔 저울에 모든 무게추를 올리는 방법은 총 몇 가지가 있을까?
2. 풀이
왼쪽 저울에 올라갈 순열을 찾는다.
cnt==N이면 다 찾은 경우이므로 result에 1을 더한다.
경우의 수를 찾다가 중간에 이미 left가 나머지+right보다 더 크면 그 뒤의 경우의 수((N-cnt)! * 2^(N-cnt))를 전부 더해주고 끝낸다.
0부터 N-1 중에 이미 뽑은 추는 제외하고 나머지를 오른쪽, 왼쪽으로 저울에 올린다. (재귀호출)
오른쪽으로 올릴 때는 left보다 right+현재 추 무게가 같거나 작을 때만 가능하다.
import java.io.*; import java.util.*; public class D4_3234_준환이의양팔저울 { private static int N, result; private static int[] weights; public static void main(String[] args) throws IOException { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st; StringBuilder sb = new StringBuilder(); int T = Integer.parseInt(in.readLine()); for (int tc = 1; tc <= T; tc++) { sb.append("#").append(tc).append(" "); result = 0; int total = 0; N = Integer.parseInt(in.readLine()); weights = new int[N]; st = new StringTokenizer(in.readLine()); for (int i = 0; i < N; i++) { weights[i] = Integer.parseInt(st.nextToken()); total += weights[i]; } measure(0, 0, 0, total, 0); sb.append(result).append("\n"); } System.out.print(sb); } private static void measure(int cnt, int left, int right, int stock, int flag) { int[] pow = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512}; int[] factorial = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}; if (cnt == N) { ++result; return; } if (left >= stock + right) { result += factorial[N - cnt] * pow[N - cnt]; return; } for (int i = 0; i < N; i++) { if ((flag & 1 << i) != 0) continue; measure(cnt + 1, left + weights[i], right, stock - weights[i], flag | 1 << i); if (left >= right + weights[i]) { measure(cnt + 1, left, right + weights[i], stock - weights[i], flag | 1 << i); } } } }
3. 결과
![[SWEA] 3234 준환이의 양팔저울 - 3. 결과 [SWEA] 3234 준환이의 양팔저울 - 3. 결과](http://t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png)
시간초과가 너무너무 많이 났던 문제였다.
그래서 2의 n제곱을 미리 만들어 놓기도 하고, 팩토리얼도 9!까지 만들어놨다. 그런데도 시간초과가 났다.
가지치기도 잘 한 것 같은데 계속 틀려서 찾아보니 total이 문제였다. total을 static변수로 설정하고 (left >= total-left) 비교했었는데 함수 내에 있는 매개변수 접근보다 전역변수 접근이 더 느려서 그랬나보다. 원거리 변수보다 근거리 변수 접근이 더 빠른 것이 당연하기는 하다.
'코딩테스트 > SWEA' 카테고리의 다른 글
[SWEA] 1238 Contact - JAVA (0) | 2022.02.22 |
---|---|
[SWEA] 1247 최적경로 - JAVA (0) | 2022.02.20 |
[SWEA] 4012 요리사 - JAVA (0) | 2022.02.16 |
[SWEA] 5644 무선충전 - JAVA (0) | 2022.02.16 |
[SWEA] 6808 규영이와 인영이의 카드게임 - JAVA (0) | 2022.02.14 |
댓글