백준 문제 풀이 & C++ 공부
백준 14620 C++
daisy0461
2024. 3. 25. 00:03
https://www.acmicpc.net/problem/14620
14620번: 꽃길
2017년 4월 5일 식목일을 맞이한 진아는 나무를 심는 대신 하이테크관 앞 화단에 꽃을 심어 등교할 때 마다 꽃길을 걷고 싶었다. 진아가 가진 꽃의 씨앗은 꽃을 심고나면 정확히 1년후에 꽃이 피므
www.acmicpc.net
n이 결국 10x10이 최대라서 완전탐색하면 쉽게 풀 수 있는데
그저 DP를 할지 진짜 완전탐색을 할지 고민하다가 그냥 완전탐색으로 풀었다.
#include <iostream>
#include <vector>
using namespace std;
int n; // 6<= n <= 10;
int g[15][15];
int visited[15][15];
int dy[] = { -1, 0, 1, 0 };
int dx[] = { 0, 1, 0, -1 };
vector<int> price;
int minR = 987654321;
bool check(int y, int x) //씨앗이 심어지는 위치를 y, x라고 하고 꽃잎의 범위가 통과하면 visited와 price를 넣는다.
{
int temp = -1;
for (int i = 0; i < 4; i++) {
int ny = y + dy[i];
int nx = x + dx[i];
if (g[ny][nx] == -1 || visited[ny][nx]) break; //범위를 벗어나거나 이미 꽃이 있는 지역이라면 for문을 나간다.
temp = i;
}
if (temp == 3) { //for문을 끝까지 돌았다면
int a = 0;
visited[y][x] = 1;
a += g[y][x];
for (int i = 0; i < 4; i++) {
int ny = y + dy[i];
int nx = x + dx[i];
visited[ny][nx] = 1; //꽃잎의 부분도 방문처리함.
a += g[ny][nx];
}
price.push_back(a);
return true;
}
else {
return false;
}
}
void release(int y, int x)
{
visited[y][x] = 0;
for (int i = 0; i < 4; i++) {
int ny = y + dy[i];
int nx = x + dx[i];
visited[ny][nx] = 0;
}
price.pop_back();
}
void go(int sy, int sx)
{
if (price.size() == 3) {
int a = 0;
for (auto i : price) {
a += i;
}
minR = min(minR, a);
return;
}
for (int i = sy; i <= n; i++) {
for (int j = sx; j <= n; j++) {
//꽃을 심을 수 없는 자리에선 굳이 재귀를 돌릴 필요가 없다.
//왜냐면 결국에 go(i)에서도 심을 수 있는 위치를 확인할건데 심은것만 돌리는게 횟수가 작지 다 돌리면 너무 크다고 생각했다.
//못심으면 그냥 다음 칸을 향해서 나아가는 것이다. 심어지면 심고 go(i)를 통해 다음 칸을 찾아 가는 것이다.
if (check(i, j)) {
go(i, j);
release(i, j);
}
}
sx = 1;
}
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> n;
fill(&g[0][0], &g[0][0] + 15 * 15, -1);
for (int i = 1; i <= n; i++) { //가든 가격 입력
for (int j = 1; j <= n; j++) {
cin >> g[i][j];
}
}
go(1, 1);
cout << minR;
}