728x90
https://www.acmicpc.net/problem/1007
문제
평면 상에 N개의 점이 찍혀있고, 그 점을 집합 P라고 하자. 집합 P의 벡터 매칭은 벡터의 집합인데, 모든 벡터는 집합 P의 한 점에서 시작해서, 또 다른 점에서 끝나는 벡터의 집합이다. 또, P에 속하는 모든 점은 한 번씩 쓰여야 한다.
벡터 매칭에 있는 벡터의 개수는 P에 있는 점의 절반이다.
평면 상의 점이 주어졌을 때, 집합 P의 벡터 매칭에 있는 벡터의 합의 길이의 최솟값을 출력하는 프로그램을 작성하시오.
입력
첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 다음과 같이 구성되어있다.
테스트 케이스의 첫째 줄에 점의 개수 N이 주어진다. N은 짝수이다. 둘째 줄부터 N개의 줄에 점의 좌표가 주어진다. N은 20보다 작거나 같은 자연수이고, 좌표는 절댓값이 100,000보다 작거나 같은 정수다. 모든 점은 서로 다르다.
출력
각 테스트 케이스마다 정답을 출력한다. 절대/상대 오차는 $10^{-6}$까지 허용한다.
728x90
예제 입력 1
2
4
5 5
5 -5
-5 5
-5 -5
2
-100000 -100000
100000 100000
예제 출력 1
0.000000000000
282842.712474619038
예제 입력 2
1
10
26 -76
65 -83
78 38
92 22
-60 -42
-27 85
42 46
-86 98
92 -47
-41 38
예제 출력 2
13.341664064126334
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
static int N;
static int[][] arr;
static boolean[] startPoint;
static double result;
private static void subset(int idx, int count) { // 벡터의 시작 점을 고르는 메소드
if(idx == N) {
if(count == N / 2) { // 딱 절반 골랐을 경우에만 벡터를 구해줌
double r = getVector();
result = Math.min(result, r);
}
return;
}
// idx가 시작점인 경우
startPoint[idx] = true;
subset(idx + 1, count + 1);
// idx가 끝점인 경우
startPoint[idx] = false;
subset(idx + 1, count);
}
private static double getVector() {
int x = 0;
int y = 0;
for (int i = 0; i < N; i++) {
if(startPoint[i]) { // 시작점이면 빼줌
x -= arr[i][0];
y -= arr[i][1];
}
else { // 끝점이면 더해줌
x += arr[i][0];
y += arr[i][1];
}
}
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine());
for (int tc = 0; tc < T; tc++) {
N = Integer.parseInt(br.readLine());
arr = new int[N][2];
for (int i = 0; i < N; i++) {
st = new StringTokenizer(br.readLine());
arr[i][0] = Integer.parseInt(st.nextToken());
arr[i][1] = Integer.parseInt(st.nextToken());
}
startPoint = new boolean[N];
result = Double.MAX_VALUE;
subset(0, 0);
sb.append(result + "\n");
}
System.out.println(sb);
}
}
728x90
'Problem Solving > BOJ' 카테고리의 다른 글
[백준, BOJ 3055] 탈출 (java) (0) | 2023.04.07 |
---|---|
[백준, BOJ 2458] 키 순서 (java) (0) | 2023.04.04 |
[백준, BOJ 1786] 찾기 (java) (0) | 2023.04.04 |
[백준, BOJ 1005] ACM Craft (java) (0) | 2023.04.03 |
[백준, BOJ 1991] 트리 순회 (java) (0) | 2023.04.03 |