https://www.acmicpc.net/problem/12869
수빈이는 강호와 함께 스타크래프트 게임을 하고 있다. 수빈이는 뮤탈리스크 1개가 남아있고, 강호는 SCV N개가 남아있다.
각각의 SCV는 남아있는 체력이 주어져있으며, 뮤탈리스크를 공격할 수는 없다. 즉, 이 게임은 수빈이가 이겼다는 것이다.
뮤탈리스크가 공격을 할 때, 한 번에 세 개의 SCV를 공격할 수 있다.
첫 번째로 공격받는 SCV는 체력 9를 잃는다.
두 번째로 공격받는 SCV는 체력 3을 잃는다.
세 번째로 공격받는 SCV는 체력 1을 잃는다.
SCV의 체력이 0 또는 그 이하가 되어버리면, SCV는 그 즉시 파괴된다. 한 번의 공격에서 같은 SCV를 여러 번 공격할 수는 없다.
남아있는 SCV의 체력이 주어졌을 때, 모든 SCV를 파괴하기 위해 공격해야 하는 횟수의 최솟값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 SCV의 수 N (1 ≤ N ≤ 3)이 주어진다. 둘째 줄에는 SCV N개의 체력이 주어진다. 체력은 60보다 작거나 같은 자연수이다.
출력
첫째 줄에 모든 SCV를 파괴하기 위한 공격 횟수의 최솟값을 출력한다.
주어진 SCV를 시작점으로 두고 레벨별로 탐색하는 bfs를 이용해서 푸는 문제다.
공격 순서를 모두 담은 이차원 배열 _a[6][3]
배열 인덱스는 음수가 될 수 없으므로 max(0, a - _a[i][0])
을 통해 음수값이 되면 0을 갖도록 한다.
#include <iostream>
#include <algorithm>
#include <queue>
using namespace std;
int n;
int a[3], visited[64][64][64];
int _a[6][3] = {
{9, 3, 1},
{9, 1, 3},
{3, 9, 1},
{3, 1, 9},
{1, 9, 3},
{1, 3, 9}
};
struct A
{
int a, b, c;
};
queue<A> q;
int solve(int a, int b, int c)
{
visited[a][b][c] = 1;
q.push({a, b, c});
while (q.size())
{
int a = q.front().a;
int b = q.front().b;
int c = q.front().c;
q.pop();
if (visited[0][0][0])
break;
for (int i = 0; i < 6; i++)
{
int na = max(0, a - _a[i][0]);
int nb = max(0, b - _a[i][1]);
int nc = max(0, c - _a[i][2]);
if (visited[na][nb][nc])
continue;
visited[na][nb][nc] = visited[a][b][c] + 1;
q.push({na, nb, nc});
}
}
return visited[0][0][0] - 1;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for (int i = 0; i < n; i++)
cin >> a[i];
cout << solve(a[0], a[1], a[2]) << "\n";
}