본문 바로가기
Programming/BOJ

#1007 벡터 매칭(Mathematics)

by 작은별하나 2019. 12. 20.
반응형

이 문제는 Gold II 문제입니다.  처음에는 동적 프로그래밍을 이용한 TSP프로그램인 줄 알고 열심히 짰다가, 예제 결과가 틀렸길래 뭐지 하고 봤었네요.  제가 문제를 풀 때만 해도 Gold I 문제였는데, 그동안 난이도가 떨어졌네요.

 

어쩐지 벡터 매칭이 문제 이름인데, TSP 문제일리가 없었죠.  그리고 TSP 문제였다면 조금 더 난이도 값이 주어졌을 것 같네요.  TSP 문제였다면, 비트매스킹을 써서 동적 프로그래밍으로 답을 해야하죠.  그 귀찮은 프로그래밍을 다 했었는데.  최대 점들의 갯수가 20개이므로, TSP 문제였다고 해도 시간안에 대충 풀었을 듯 합니다.

 

 

문제는 2차원 공간상에 점들이 주어지면, 이 점들중 두개씩 짝을 이루어 벡터를 만들었을 때, 그 벡터들의 합이 최소가 되도록 하는 것입니다.

 

문제는 아래의 링크입니다.

https://www.acmicpc.net/problem/1007

 

1007번: 벡터 매칭

평면 상에 N개의 점이 찍혀있고, 그 점을 집합 P라고 하자. 집합 P의 벡터 매칭은 벡터의 집합인데, 모든 벡터는 집합 P의 한 점에서 시작해서, 또 다른 점에서 끝나는 벡터의 집합이다. 또, P에 속하는 모든 점은 한 번씩 쓰여야 한다. V에 있는 벡터의 개수는 P에 있는 점의 절반이다. 평면 상의 점이 주어졌을 때, 집합 P의 벡터 매칭에 있는 벡터의 합의 길이의 최솟값을 출력하는 프로그램을 작성하시오.

www.acmicpc.net

 

이 문제에서 중요한 것은 점들 중 절반은 더하기를 나머지 절반은 빼기를 한 결과의 길이값이 가장 적도록 하면 됩니다.

가장 무식한 방법으로 풀어보자면, 순회를 하면서 절반을 선택하는 방법입니다.  최대 점들의 갯수는 20개이므로, 20개중 10개를 선택하는 경우의 수가 너무 크지 않으면 됩니다.

 

\[ \binom{20}{10} = 184,756 \]

 

10만 단위의 경우의 수이면 테스트 케이스가 몇천 단위가 아닌 이상 시간안에 들어오는 경우의 수입니다.  AC를 받을 때 48ms 받았습니다.  더 좋은 결과를 낸 사람들도 많네요.

 

이 문제는 \(V_i + V_j\) 를 하게 되면, 각각의 벡터의 크기를 합하면 됩니다.  그래서 20개중에 10개의 점은 더하고, 10개의 점은 빼서 최종적으로 얻어진 벡터의 길이를 구하면 됩니다.

 

다음은 제가 작성한 소스입니다.  소스는 참고용으로 봐주세요.

//----------------------------------------------------------
//  baekjoon #1007 - Vector Matching
//    - by Aubrey Choi
//    - created at 2019-12-29
//----------------------------------------------------------
#include <stdio.h>
#include <math.h>

int n, x[20], y[20];
double getOpt(int c, int p, int m, int xs, int ys)
{
  if(c==n) return sqrt((double)xs*xs+(double)ys*ys);
  double min=1e10, r;
  if(p<n/2) { r=getOpt(c+1, p+1, m, xs+x[c], ys+y[c]); min=(r<min)?r:min; }
  if(m<n/2) { r=getOpt(c+1, p, m+1, xs-x[c], ys-y[c]); min=(r<min)?r:min; }
  return min;
}
int main()
{
  int t, i, j;
  scanf("%d",&t);
  while(t--)
  {
    scanf("%d",&n);
    for(i=0;i<n;i++) scanf("%d%d",x+i,y+i);
    printf("%.8lf\n", getOpt(0, 0, 0, 0, 0));
  }
}

 

728x90

'Programming > BOJ' 카테고리의 다른 글

[C/C++] 백준 #1010 다리 놓기(조합)  (0) 2019.12.21
백준 #1009 분산처리  (0) 2019.12.20
[C/C++] 백준 #1005 ACM Craft(위상 정렬)  (0) 2019.12.19
백준 #1004 어린왕자  (0) 2019.12.19
백준 #1003 피보나치 함수  (0) 2019.12.16

댓글