[SWEA]3234号:ジュンファンの両腕秤(Java)
質問する
SW Expert Academy(SWEA)3234ジュンファンの両腕秤[D 4]
に答える
両腕秤の順番を決める
どの辺に配置するかを指定します=>サブセット
入力を受け入れ、優先的に配置する重量を決定します.
完了したシーケンスをソートされた配列に保存し、シーケンスが完了した場合(cnt=N)にどちらに配置するかを指定します.
現在のボタンを右側に配置すると、各ボタンを左側に配置します.
運転中、左側<右側の場合は、枝による時間短縮(逆トレース)
基本条件が満たされている場合は、状況の数を増やして終了します.
コード#コード#
import java.io.*;
import java.util.*;
public class Solution{
static int N, res;
static int[] weight,sorted;
static boolean[] isSelected;
public static void main(String[] args) throws Exception{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int tc = Integer.parseInt(br.readLine());
for(int T = 1 ; T<=tc ; T++) {
N = Integer.parseInt(br.readLine());
weight = new int[N];
sorted = new int[N];
isSelected = new boolean[N];
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for(int i =0 ; i < N ; i++) {
weight[i] = Integer.parseInt(st.nextToken());
}
res = 0;
perm(0);
sb.append("#").append(T).append(" ").append(res).append("\n");
}
System.out.println(sb.toString());
br.close();
}
//왼쪽, 오른쪽 관계없이 올려놓는 순서를 정하는 '순열'함수
private static void perm(int cnt) {
if(cnt == N) { //기저조건
scale(0,0,0);
}
//순열 만들기
for(int i = 0 ; i < N ; i++) {
if(isSelected[i]) continue;
sorted[cnt] = weight[i]; //sorted: 순열결과를 저장(인덱스 저장이 아닌 값 저장)
isSelected[i] = true; // 현재 인덱스 선택처리
perm(cnt+1);
isSelected[i] = false; // 선택 처리 초기화
}
}
//순열함수의 결과값을 이용해서 양팔저울에 올릴 경우의 수를 계산하는 '부분집합'함수
private static void scale(int cnt, int left, int right) {
if(left<right) return; //가지치기(현재 왼쪽의 무게보다 오른쪽의 무게가 많을 때)
if(cnt == N) { //기저조건
res++; //경우의 수 증가
return;
}
scale(cnt+1, left, right+sorted[cnt]); //오른쪽에 올렸을 때
scale(cnt+1, left+sorted[cnt], right); //왼쪽에 올렸을 때
}
}
Reference
この問題について([SWEA]3234号:ジュンファンの両腕秤(Java)), 我々は、より多くの情報をここで見つけました https://velog.io/@dot2__/SWEA-3234번-준환이의-양팔저울-Javaテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol