황토색 토지에 들어갈 배양액들의 모든 경우의 수 구하기
BFS를 통해 배양액을 확산시키기
풀이는 상당히 간단해 보이지만 숨은 디테일들을 잘 살려서 풀어야 한다.
이 함수를 사용하면 굉장히 간편하게 모든 경우의 수를 찾게된다.
추가적으로 2개의 매개체를 돌릴때는 시간을 잘 확인해야 한다... 이 부분 때문에 상당히 막혔다.
큐 안에 꽃이 핀 곳으로의 배양액이 들어있을 수 있다. 그래서 큐에서 꺼낼때 마다 항상 확인을 해줘야 한다.
현재 꺼낸 배양액의 위치에 꽃이 폈는지 확인하는 것이다.
#include <bits/stdc++.h>
using namespace std;
typedef struct node {
int x;
int y;
};
int n, m, g, r;
int Max = 0;
// 사용할 순열 구하기용
int used[10];
int Map[51][51];
pair<int, int> state[51][51]; // 색깔, 시간
int dx[] = { 0,0,-1,1 };
int dy[] = { 1,-1,0,0 };
vector<node> y;
queue<node> q;
void bfs()
{
for (int i = 0; i < n; i++)
{
fill(state[i], state[i] + m, make_pair(0,-1));
}
// q에 값 넣기 ( used에 사용할 그거 나와있음 )
for (int i = 0; i < y.size(); i++)
{
// green
if (used[i] == 1)
{
state[y[i].x][y[i].y] = { 1,0 };
q.push({ y[i].x, y[i].y });
}
else if (used[i] == 2)
{
state[y[i].x][y[i].y] = { 2,0 };
q.push({ y[i].x, y[i].y });
}
}
int flower = 0;
// 빨간약,초록약이 뿌려진 위치가 담긴 큐에서 BFS 돌리기
while (!q.empty())
{
int cx = q.front().x;
int cy = q.front().y;
int ccolor = state[cx][cy].first;
int cdep = state[cx][cy].second;
q.pop();
// 현재 위치에 꽃이 폈다면
if (state[cx][cy].first == 3) continue;
for (int i = 0; i < 4; i++)
{
int nx = cx + dx[i];
int ny = cy + dy[i];
int ndep = cdep + 1;
// 호수거나 꽃이라면
if (nx < 0 || ny < 0 || nx >= n || ny >= m || Map[nx][ny] == 0 || state[nx][ny].first == 3)
continue;
// 아직 닿지 않은 곳이라면
if (state[nx][ny].first == 0)
{
state[nx][ny].first = ccolor;
state[nx][ny].second = ndep;
q.push({ nx,ny });
}
// 꽃이 필 자리이면 (시간이 같고, 색깔이 다를 경우)
else if (state[nx][ny].second == ndep && (state[nx][ny].first + ccolor == 3))
{
state[nx][ny] = make_pair(3, ndep);
flower++;
}
}
}
Max = max(Max, flower);
return;
}
// 하얀칸 : 배양액 못뿌림 , 황토칸 : 배양액 뿌릴수있 , 하늘색 : 호수
int main()
{
cin >> n >> m >> g >> r;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
// 0 : 호수, 1 : 흰색칸, 2 : 황토칸
cin >> Map[i][j];
if (Map[i][j] == 2)
{
y.push_back({ i,j });
}
}
}
int blanc = y.size() - g - r;
fill(used + blanc, used + blanc + g, 1);
fill(used + blanc + g, used + y.size(), 2);
do {
bfs();
} while (next_permutation(used, used + y.size()));
cout << Max;
return 0;
}
개인적으로 꼬박 이틀 걸려서 푼 문제인데
무슨 이딴 문제가 다있나 싶으면서도 풀다보니 정말 잘 만들었다 느꼈다.
이런 문제들이 코테로 나온다면 이제는 풀 수 있을거라 생각한다.
이런 문제들이 계속 나와주면 좋겠다 ㅎㅎ
next_permutation 꼭 활용하자
조합, 순열은 이 함수가 캐리한다