기술 블로그

17259번 선물이 넘쳐흘러 본문

알고리즘 문제/BOJ

17259번 선물이 넘쳐흘러

parkit 2019. 8. 10. 16:36
728x90
반응형

https://www.acmicpc.net/problem/17259




핸드폰 게임하면서, 푼 문제라서 다소 코드가 깨끗하지 못 하고, 변수명이 헷갈릴 수 있다.


처음 제출했을 때 틀렸었는데,


알고보니 isExit() 함수 내에서 present만 검사하였다.


person도 검사해야 선물이 완전히 없어지는 것을 검사할 수 있다.



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
#include <bits/stdc++.h>
 
using namespace std;
 
int B, N, M, T[101][101], person[101][101], answer;
 
int dy[3= { 10-1 };
int dx[3= { 010 };
 
bool present[101][101];
 
vector<pair<intint> > v;
 
bool isExit()
{
    for (int i = 0; i < B; i++)
        for (int j = 0; j < B; j++)
            if (present[i][j])
                return false;
 
    for (int i = 0; i < B; i++)
        for (int j = 0; j < B; j++)
            if (person[i][j] != -1)
                return false;
 
    return true;
}
 
void simulation()
{
    // 시뮬레이션 실행
    while (1)
    {
        // 끝난 포장이 있는지 체크
        for (auto i : v)
        {
            if (person[i.first][i.second] == T[i.first][i.second])
            {
                ++answer;
                person[i.first][i.second] = -1;
            }
        }
 
        if (isExit()) break;
 
        // 포장 중이지 않은 사람들의 좌표에서 (하, 우, 상)에 선물이 있는지 검사 
        for (auto i : v)
        {
            // 포장 중이지 않다면(= -1)
            if (person[i.first][i.second] == -1)
            {
                // 그 사람 주변 (하, 우, 상)을 검사
                for (int idx = 0; idx < 3; idx++)
                {
                    int y = i.first + dy[idx];
                    int x = i.second + dx[idx];
 
                    // 범위를 초과하거나 (하, 우, 상) 칸에 선물이 없으면 continue
                    if (y < 0 || y >= B || x < 0 || x >= B || !present[y][x]) continue;
 
                    person[i.first][i.second] = 0;
                    present[y][x] = false;
 
                    // 어차피 동시에는 최대 한 개만 포장 가능
                    break;
                }
            }
        }
 
        // 선물 이동 열 →
        bool re = present[0][B - 1];
        for (int c = B - 1; c >= 1; c--)
            present[0][c] = present[0][c - 1];
 
        if (M > 0)
        {
            present[0][0= true;
            --M;
        }
        else present[0][0= false;
 
        // 선물 이동 행 ↓
        bool ce = present[B - 1][B - 1];
        for (int r = B - 2; r >= 1; r--)
            present[r + 1][B - 1= present[r][B - 1];
        present[1][B - 1= re;
 
        // 선물 이동 열 ←
        for (int c = 0; c < B - 2; c++)
            present[B - 1][c] = present[B - 1][c + 1];
        present[B - 1][B - 2= ce;
 
        // 시간 증가
        for (auto i : v)
            if (person[i.first][i.second] != -1)
                ++person[i.first][i.second];
    }
}
 
int main(void)
{
    int r, c, t;
 
    memset(T, -1sizeof(T));
    memset(person, -1sizeof(person));
 
    scanf("%d %d %d"&B, &N, &M);
 
    for (int i = 0; i < N; i++)
    {
        scanf("%d %d %d"&r, &c, &t);
        T[r][c] = t;
        v.push_back({ r, c });
    }
 
    --M;
    present[0][0= true;
 
    simulation();
    
    printf("%d\n", answer);
 
    return 0;
}
cs







728x90
반응형

'알고리즘 문제 > BOJ' 카테고리의 다른 글

2042번 구간 합 구하기  (0) 2019.08.16
2234번 성곽  (0) 2019.08.15
1726번 로봇  (0) 2019.08.05
14395번 4연산  (0) 2019.07.18
17298번 오큰수  (0) 2019.07.06