[백준 15661번 C++] 링크와 스타트
[백준 15661번 C++] 링크와 스타트

https://www.acmicpc.net/problem/15661
해결전략
비트마스킹 Bitmasking
백트래킹 Backtracking
정답코드 - 비트 마스킹
#include <iostream> #include <vector> #include <algorithm> using namespace std; int n; // 팀의 인원 수 int answer = 987654321; vector<vector<int>> v; int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n; v.resize(n, vector<int>(n)); for (int y = 0; y < n; y++) { for (int x = 0; x < n; x++) { cin >> v[y][x]; } } // 모든 가능한 팀 조합을 비트마스크로 생성 for (unsigned int bitmask = 0; bitmask < (1 << n); bitmask++) { vector<int> teamStart, teamLink; // 두 팀을 저장 // 비트마스크를 통해 팀을 나누는 과정 for (int i = 0; i < n; i++) { if (bitmask & (1 << i)) { teamStart.push_back(i); } else { teamLink.push_back(i); } } //sort(teamStart.begin(), teamStart.end()); //sort(teamLink.begin(), teamLink.end()); // 각 팀의 능력치 합 계산 int sumStart = 0, sumLink = 0; for (int i = 0; i < teamStart.size(); i++){ for (int j = 0; j < teamStart.size(); j++) { sumStart += v[teamStart[i]][teamStart[j]]; } } for (int i = 0; i < teamLink.size(); i++) { for (int j = 0; j < teamLink.size(); j++) { sumLink += v[teamLink[i]][teamLink[j]]; } } answer = min(answer, abs(sumStart - sumLink)); } cout << answer; return 0; }
정답코드 - 백트래킹, 재귀
#include <iostream> #include <vector> #include <cmath> using namespace std; int n; // 팀의 인원 수 int answer = 987654321; vector<vector<int>> v; vector<bool> ch; // 각 인원이 어떤 팀에 속하는지 표시하는 벡터 // 팀의 능력치 합을 계산하는 함수 int calculateTeamScore(const vector<int>& teamMembers) { int score = 0; for (int i = 0; i < teamMembers.size(); ++i) { for (int j = 0; j < teamMembers.size(); ++j) { score += v[teamMembers[i]][teamMembers[j]]; } } return score; } // 백트래킹을 이용하여 모든 팀 구성을 탐색하는 함수 void backtrack(int idx, int count) { if (idx == n) { if (count == 0 || count == n) return; // 한 팀이 비어있는 경우는 무시 vector<int> teamStart, teamLink; for (int i = 0; i < n; ++i) { if (ch[i]) { teamStart.push_back(i); } else { teamLink.push_back(i); } } // 각 팀의 능력치 합 계산 int sumStart = calculateTeamScore(teamStart); int sumLink = calculateTeamScore(teamLink); // 두 팀의 능력치 차이의 절대값을 계산하여 최소값 업데이트 answer = min(answer, abs(sumStart - sumLink)); return; } // 현재 인원을 teamStart에 추가하는 경우 ch[idx] = true; backtrack(idx + 1, count + 1); // 현재 인원을 teamLink에 추가하는 경우 ch[idx] = false; backtrack(idx + 1, count); } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n; v.resize(n, vector<int>(n)); ch.resize(n); for (int y = 0; y < n; ++y) { for (int x = 0; x < n; ++x) { cin >> v[y][x]; } } backtrack(0, 0); // 백트래킹 시작 cout << answer; return 0; }
'⭐ 코딩테스트 > 백준' 카테고리의 다른 글
[백준 2098번 C/C++] 외판원 순회 (0) | 2024.08.08 |
---|---|
[백준 14391번 C/C++] 종이 조각 (0) | 2024.08.07 |
[백준 11723번 C/C++] 집합 (0) | 2024.08.05 |
[백준 1052번 C/C++] 물병 (0) | 2024.08.05 |
[백준 16938번 C/C++] 캠프 준비 (0) | 2024.08.02 |
댓글
이 글 공유하기
다른 글
-
[백준 2098번 C/C++] 외판원 순회
[백준 2098번 C/C++] 외판원 순회
2024.08.08[백준 2098번 C/C++] 외판원 순회 https://www.acmicpc.net/problem/2098 해결전략 비트마스킹 Bitmasking동적계획법 Dynamic Programming, DP비트필드를 이용한 다이나믹 프로그래밍 외판원 순회 문제 정답 코드 #include #include #include using namespace std;int n; // 도시의 수vector> W; vector> dp;const int INF = 2147000000;int TSP(int cur, int visited){ // visited의 모든 비트가 1이라면(즉, 모든 도시를 방문했다면), 현재 도시에서 시작 도시로 돌아가는 비용을 반환 if (visited == (1 > n; W.res… -
[백준 14391번 C/C++] 종이 조각
[백준 14391번 C/C++] 종이 조각
2024.08.07[백준 14391번 C/C++] 종이 조각 https://www.acmicpc.net/problem/14391 해결전략 비트마스킹 Bitmasking 정답코드 #include #include #include using namespace std;int n, m;int answer = 0;vector> v;int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> n >> m; v.resize(n, vector(m)); for (int y = 0; y > c; v[y][x] = c - '0'; // 문자를 숫자로 변환 } } // Rule 정하기: 0이면 세로, 1이… -
[백준 11723번 C/C++] 집합
[백준 11723번 C/C++] 집합
2024.08.05[백준 11723번 C/C++] 집합 https://www.acmicpc.net/problem/11723 해결전략 비트마스킹 Bitmasking 정답 코드 #include using namespace std;int m;int answer;int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin >> m; string input, int x; for (int i = 0; i > input; if (input == "add"){ cin >> x; answer |= (1 > x; answer &= ~(1 > x; if (answer & (1 > x; answer ^= (1 -
[백준 1052번 C/C++] 물병
[백준 1052번 C/C++] 물병
2024.08.05[백준 1052번 C/C++] 물병 https://www.acmicpc.net/problem/1052 해결전 수학 그리디 알고리즘 비트마스킹 각 물병은 서로 다른 물병과 합쳐질 수 있다. 이 합치는 과정은 물병의 2진수로 표현한다.예를 들어, 물병 3개(2진수로 11)를 2개씩 합치면 2진수 100이 되어 물병 1개가 된다. 물병을 모두 합쳐서 k개의 물병 이하로 만들어야 한다.n이 k보다 작거나 같으면 추가 물병이 필요 없으므로 0을 반환합니다.비트마스킹n의 2진수 표현에서 1의 개수는 현재 물병의 수가 어떻게 조합될 수 있는지를 나타낸다.int BitCnt(int x)n의 2진수 표현에서 1의 개수가 k보다 많으면, 물병을 추가하여 이 개수를 줄여야 한다. 이를 위해 n을 하나씩 증가시키면서 1의 …
댓글을 사용할 수 없습니다.