문제 URL : https://www.acmicpc.net/problem/21610
문제 접근법 : 예외처리할것도 없고 문제설명이 잘되어있어 말장난 이라고될만한게 설명이 없다시피했네요
하나있다면 설명이 3번 구름을 모두제거한다인데 3번을 미리 제거하게되면 문제설명 4번과 5번을 할수가없으니 4,5번후에 3번을 하시는게 포인트입니다.
그리고 좌표를 (1,1)~(n,n)을 사용하면 나머지연산이 더어려워지니 (0,0)~(n-1,n-1)를 사용합니다.
그리고 이동은 경계선 밖으로나가면 다시 반대쪽 경계선으로 들어오도록 if문 사용할필요없이
이동해야할 방향만큼 *s를 곱해서 더한다면 왼쪽이나 위로 이동할때는 음수가 나오는 경우가 있기때문에
n*s만큼더한후 다더해준다음 다시 n으로 나눈 나머지를 하면 됩니다.
소스코드 :
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
|
//By 콩순이냉장고
#include <bits/stdc++.h>
using namespace std;
#define v vector
#define vi v<int>
#define vvi v<v<int>>
#define pii pair<int,int>
#define vpii v<pii>
int n, m;
vvi board,cloud;
vpii mv;
int dy[8] = { 0,-1,-1,-1,0,1,1,1 };
int dx[8] = { -1,-1,0,1,1,1,0,-1 };
void input(){
int d, s;
cin >> n >> m;
board = vvi(n, vi(n));
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
cin >> board[i][j];
}
}
for (int i = 0; i < m; i++) {
cin >> d >> s;
mv.push_back({ d - 1,s });
}
}
bool isrange(int y, int x) { return 0 <= y && y < n && 0 <= x && x < n; }
void setcloud(vpii &cv){
cloud = vvi(n, vi(n));
for (pii t : cv)
cloud[t.first][t.second] = 1;
}
void makecloud(vpii& cv) {
cv.clear();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (cloud[i][j]||board[i][j]<2)continue;
board[i][j] -= 2;
cv.push_back({ i,j });
}
}
}
void solve() {
vpii cv = { {n - 1,0},{n - 1,1},{n - 2,0},{n - 2,1} };
for (pii move : mv) {
int d, s;
vpii temp;
tie(d, s) = { move.first , move.second };
// 1~2번 모든구름이 d방향으로 s칸 만큼이동후 1증가
for (int i = 0; i < cv.size(); i++) {
int ny = (cv[i].first + dy[d] * s + n * s) % n;
int nx = (cv[i].second + dx[d] * s + n * s) % n;
temp.push_back({ ny,nx });
board[ny][nx]++;
}
//3번 구름이 모두사라지면4번을 할수가없음 맨나중에해야함
//4번 구름에있던자리 물복사시전
for (int i = 0; i < temp.size(); i++) {
int cnt = 0;
for (int j = 1; j < 8; j += 2) {
int ny = temp[i].first + dy[j];
int nx = temp[i].second + dx[j];
if (isrange(ny, nx) && board[ny][nx])cnt++;
}
board[temp[i].first][temp[i].second] += cnt;
}
//구름이 어디에있는지
setcloud(temp);
//5번구름생성
makecloud(cv);
//3번은 temp.clear()를 통해서 해야하지만 temp가 스스로 셋팅되기때문에 없어도됨
}
int res = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
res += board[i][j];
}
}
cout << res << "\n";
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
//freopen("input.txt", "r", stdin);
input();
solve();
}
|
cs |
궁금한점 혹은 모르는점 어떤질문이든 댓글은 언제나 환영입니다.
'백준' 카테고리의 다른 글
백준 13505 두 수 XOR (0) | 2021.08.22 |
---|---|
백준 14906 스러피 (0) | 2021.08.19 |
백준 13900 순서쌍의 곱의 합 (0) | 2021.08.16 |
백준 1024 수열의합 (0) | 2021.08.15 |
백준 1043 거짓말 (0) | 2021.08.15 |