백준/실랜디, 골랜디
[백준] C++ 스타트와 링크(14889)
2zreal
2025. 1. 9. 16:45
이 문제는 조합을 이용하는 문제이다. 모든 경우의 수를 확인해서 차이가 최소인 값을 출력하면 된다.
1, 2, 3, 4가 있으면 (1,2 / 3,4), (1,3 / 2,4), (1,4 / 2,3) 이 경우에 대해서만 확인을 하면 된다.
문제해결방법
1. 모든 경우의 조합에 대해 확인한다. (6명이 있으면 3명만 뽑는다. 나머지 3명은 남는 사람으로 따로 계산)
2. 스타트 팀과 링크팀의 차이를 구한다.(abs(스타트-링크))
#include <iostream>
#include <vector>
using namespace std;
void DFS(int size, int count, int start);
vector<int>v[1000];
int visited[1000];
int result = 987654321;
int main(void)
{
int N = 0;
cin >> N;
int num = 0;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < N; j++)
{
cin >> num;
v[i].push_back(num);
}
}
DFS(v[0].size(), 0, 0);
cout << result;
return 0;
}
void DFS(int size, int count, int start)
{
if (count == size / 2)//만약 절반만큼 인원을 뽑았다면 이제는 계산을 하자
{
int num1 = 0;
for (int i = 0; i < size; i++)//스타트팀 계산
{
if (visited[i] == 1)
{
for (int j = 0; j < size; j++)
{
if (i != j && visited[j] == 1)
{
num1 += v[i][j];
}
}
}
}
int num2 = 0;
for (int i = 0; i < size; i++)//링크팀 계산
{
if (visited[i] == 0)
{
for (int j = 0; j < size; j++)
{
if (i != j && visited[j] == 0)
{
num2 += v[i][j];
}
}
}
}
int sum = abs(num1 - num2);
if (sum < result)
{
result = sum;
}
}
else
{
for (int i = start; i < size; i++)// 인원을 뽑는다.(중복 방지를 위해 start를 사용)
{
if (visited[i] == 0)
{
visited[i] = 1;
DFS(size, count + 1, i);
visited[i] = 0;
}
}
}
}
생각보다 어렵지 않은 문제이다. 모든 경우의 수를 DFS로 확인하면서 차이가 최소가 되는 값을 찾으면 된다.