728x90
https://www.acmicpc.net/problem/16987
16987번: 계란으로 계란치기
원래 프로그래머의 기본 소양은 팔굽혀펴기를 단 한 개도 할 수 없는 것이라고 하지만 인범이는 3대 500을 넘기는 몇 안되는 프로그래머 중 한 명이다. 인범이는 BOJ에서 틀린 제출을 할 때마다 턱
www.acmicpc.net
접근 방법
전형적인 백트래킹 문제이다.
순서대로 계란을 집어, 나머지 계란 중 하나를 치면 되는 문제이다.
이 문제의 핵심은 조건문을 어떻게 작성하냐 이다.
내가 틀렸던 예제는 다음과 같다.
3
1 4
8 1
3 1
// 정답: 2
손에 든 계란 외에 모든 계란이 깨진 경우를 체크해주지 않아 답이 1이 나왔다.
이를 bool flag를 통해 쉽게 수정하였다.
코드
#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;
#define MAX 10
int n;
vector<pair<int, int>> v;
int used[MAX];
int res;
void func(int idx, int cnt) {
if (idx >= (n+1)) {
res = max(res, cnt);
return;
}
// 자신이 깨졌으면 패스
if (used[idx] < 1) {
func(idx + 1, cnt);
}
else{
bool flag = false;
for (int i = 1; i <= n; i++) {
// 자기 자신이거나 내구도가 0이하이면 패스
if (i == idx || used[i] < 1) {
continue;
}
// 계란 치고 백트래킹
else {
used[i] -= v[idx].second;
used[idx] -= v[i].second;
if (used[i] < 1 && used[idx] < 1) {
// 둘 다 깨진 경우
func(idx + 1, cnt + 2);
}
else if (used[i] < 1) {
// 나머지 중 하나가 깨진 경우
func(idx + 1, cnt + 1);
}
else if (used[idx] < 1) {
// 들고 있는 것이 깨진 경우
func(idx + 1, cnt + 1);
}
else {
// 둘 다 깨지지 않은 경우
func(idx + 1, cnt);
}
flag = true;
used[i] += v[idx].second;
used[idx] += v[i].second;
}
}
// 들고 있는 계란 외에 모두 깨진 경우
if (!flag) func(n + 1, cnt);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n;
v.push_back(make_pair(0, 0));
for (int i = 1; i <= n; i++) {
int a, b;
cin >> a >> b;
v.push_back(make_pair(a, b));
used[i] = a;
}
func(1, 0);
cout << res;
}

728x90
'📊알고리즘 > BOJ' 카테고리의 다른 글
BOJ 2206 - 벽 부수고 이동하기 (0) | 2024.03.05 |
---|---|
BOJ 1799 - 비숍 (🔄) (0) | 2024.02.29 |
[그리디 #21] BOJ 7570 - 줄 세우기 (0) | 2024.02.27 |
[그리디 #20] BOJ 2212 - 센서 (0) | 2024.02.25 |
[백트래킹 #1] BOJ 15649 - N과 M (1) (0) | 2024.02.23 |