본문 바로가기

Problem/Brute force

[C/C++] BOJ 14620 :: 꽃길

BOJ 14620 :: 꽃길



문제 링크 : https://www.acmicpc.net/problem/14620





완전탐색으로 푸는 문제이다.


시간을 줄이기위해 고려해야 할 것.


1. 씨앗을 놓을 곳만 체크해가며 탐색한다. ==> 꽃잎 다 놓으면서 탐색하면 안됨!

2. 씨앗을 놓을 수 없는 곳을 건너뛰면서 탐색한다. ==> 이미 놓을 수 없다고 결론이 난 곳을 더 탐색하면 시간만 낭비될 뿐!




나의 코드



Github : https://github.com/j2wooooo/Daliy_Algorithms/blob/master/Daliy_Algorithms/BOJ_14620/BOJ_14620.cpp




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
// 백준 알고리즘 14620번 :: 꽃길
#include<iostream>
#include<vector>
using namespace std;
 
int N, G;
int ans = -1;
vector<pair<intint>> available;
int visited[15][15];
int grid[15][15];
 
// 탐색했을 때 꽃잎이 겹치는 위치
// 아래 세 가지 경우는 하지 않음. 위에서부터 순차적으로 탐색해나가므로 아래에 겹치는 꽃잎은 없다.
int dx[8= { 00-1-1-2-100 };
int dy[8= { -2-1-100112 };
 
// 격자에 씨앗을 채워나가는 함수
// start : 앞으로 격자에 놓을 수 있는 씨앗의 맨 처음 위치
// count : 놓은 씨앗의 개수
void fillgrid(int start, int count)
{
    bool flag = false;
 
    // 씨앗을 3개 놓았을 때, 최소 비용을 갱신한다.
    if (count == 3)
    {
        int price = 0;
        for (int m = 2; m < N+2; m++)
        {
            for (int n = 2; n < N+2; n++)
            {
                if (visited[m][n])
                {
                    price += grid[m][n] + grid[m-1][n] + grid[m+1][n] + grid[m][n-1+ grid[m][n+1];
                }
            }
        }
        if (ans > price || ans < 0) ans = price;
        return;
    }
 
    // 씨앗을 놓을 위치를 결정한다.
    for (size_t i = start; i < available.size(); i++)
    {
        int x = available[i].first;
        int y = available[i].second;
 
        // 씨앗을 놓을 위치에 꽃잎이 겹치는 경우가 생기는지 확인한다.
        for (int k = 0; k < 8; k++)
        {
            int mx = x + dx[k];
            int my = y + dy[k];
 
            // 씨앗을 놓지 않은 곳이 씨앗을 놓을 수 없는 위치이다 = 꽃잎이 겹칠 
            if (visited[mx][my]) {
                flag = true;  break;
            }
        }
 
        // 꽃잎이 겹친다. => 씨앗을 놓을 위치를 다음 위치로 넘긴다.
        if (flag) {
            flag = !flag;  continue;
        }
        // 꽃잎이 겹치지 않는다. ==> 씨앗을 높을 수 있다.
        // 다음으로 놓을 수 있는 씨앗의 시작 위치와 놓은 씨앗의 개수를 갱신하여 재귀적으로 반복한다.
        else
        {
            visited[x][y] = true;
            fillgrid(i + 1, count + 1);
            visited[x][y] = false;
        }
    }
}
 
int main()
 {
    cin >> N;
 
    // 꽃잎이 겹치는지 왼쪽으로 2칸이동, 위로 2칸이동, 오른쪽으로 2칸이동하여 확인하기 때문에
    // 데이터를 배열의 2번째 행,열부터 채운다.
    for (int i = 2; i < N+2; i++)
    {
        for (int j = 2; j < N+2; j++)
        {
            cin >> grid[i][j];
            if (i == 2 || i == N + 1 || j == 2 || j == N + 1continue;
            available.push_back(make_pair(i, j));
        }
    }
 
    for (size_t i = 0; i < available.size(); i++)
    {
        int x = available[i].first;
        int y = available[i].second;
        
        visited[x][y] = true;
        fillgrid(i + 11);
        visited[x][y] = false;
    }
 
    cout << ans;
 
    return 0;
}
cs


'Problem > Brute force' 카테고리의 다른 글

[C/C++] BOJ 1079 :: 마피아  (0) 2019.02.04
[C/C++] BOJ 15686 :: 치킨 배달  (0) 2019.02.04
[C/C++] BOJ 1062 :: 가르침  (0) 2019.01.21
[C/C++] BOJ 1018 :: 체스판 다시 칠하기  (0) 2019.01.21
[C/C++] BOJ 15684 :: 사다리 조작  (0) 2019.01.20