Algorithm, Data structure/Solved Algorithmic Problem

BAEKJOON 1028 - 다이아몬드 광산

JaykayChoi 2016. 8. 11. 00:00

문제: https://www.acmicpc.net/problem/1028



memoization 과 현재 최대값보다 작은 다이아몬드는 계산하지 않는 가지치기 방법으로 시간 복잡도를 줄여 풀었습니다.



my solving

c++

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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
#include <fstream>
#include <iostream>
#include <cstring>
#include <climits>
#include <algorithm>
 
#include <string>
using namespace std;
 
namespace Dir
{
    enum Dir { southeast, southwest, northwest, northeast };
}
 
const int MAX_N = 750;
int height, width;
int map[MAX_N + 1][MAX_N + 1];
int cache[MAX_N + 1][MAX_N + 1][4];
 
void getMovingPoint(Dir::Dir dir, int& y, int& x, int step)
{
    if (step <= 0)
        return;
    switch (dir)
    {
    case Dir::southeast:
        y += step; x += step;
        break;
    case Dir::southwest:
        y += step; x -= step;
        break;
    case Dir::northwest:
        y -= step; x -= step;
        break;
    case Dir::northeast:
        y -= step; x += step;
        break;
    default:
        break;
    }
}
 
int getMaxMovingStep(Dir::Dir dir, int y, int x)
{
    int& step = cache[y][x][dir];
    
    if (step != -1)
        return step;
    
    step = 0;
    int nextY = y;
    int nextX = x;
    while (true)
    {
        switch (dir)
        {
        case Dir::southeast:
            nextY++; nextX++;
            break;
        case Dir::southwest:
            nextY++; nextX--;
            break;
        case Dir::northwest:
            nextY--; nextX--;
            break;
        case Dir::northeast:
            nextY--; nextX++;
            break;
        default:
            break;
        }
        if (nextY < || nextY >= height || nextX < || nextX >= width)
            break;
        if (map[nextY][nextX] != 1)
            break;
        else
            step++;
    }
    return step;
}
 
bool isDiamond(int y, int x, int step)
{
    getMovingPoint(Dir::southeast, y, x, step);
 
    if (getMaxMovingStep(Dir::southwest, y, x) < step)
        return false;
    getMovingPoint(Dir::southwest, y, x, step);
 
    if (getMaxMovingStep(Dir::northwest, y, x) < step)
        return false;
    getMovingPoint(Dir::northwest, y, x, step);
 
    if (getMaxMovingStep(Dir::northeast, y, x) < step)
        return false;
    else
        return true;
}
 
int getMaxDiamond()
{
    int ret = 0;
    for (int y = 0; y < height; y++)
    {
        for (int x = 0; x < width; x++)
        {
            if (map[y][x] == 1)
            {
                if (ret == 0)
                    ret++;
 
                int step = getMaxMovingStep(Dir::southeast, y, x);
 
                for (int i = step; step > ret - 1; step--)
                {
                    if (isDiamond(y, x, step))
                        ret = step + 1;
                }
            }
        }
    }
    return ret;
}
 
int main()
{
    memset(cache, -1sizeof(cache));
    memset(map, -1sizeof(map));
 
    cin >> height >> width;
 
    for (int i = 0; i < height; i++)
    {
        string str;
        cin >> str;
        for (int j = 0; j < width; j++)
            map[i][j] = str[j] - '0';
    }
    
    cout << getMaxDiamond() << endl;
    return 0;
}
cs