반응형
알고리즘 종류
구현
사고 과정
1. 말의 상태를 담을 수 있는 배열이 필요할 것 같았습니다. 그래서 Piece라는 구조체를 만들고, 이 구조체로 ps라는 배열을 만들었습니다. 구조체에는 말의 위치(y, x)와 방향(d) 그리고 맨 밑인지(isButtom)를 확인하는 변수들이 있습니다.
2. 말을 쌓을 수 있어야 합니다. 그래서 3차원 벡터를 만들기로 했습니다. state라는 명을 붙였습니다.
3. 이제 턴 1회당 밑에 있는 말만 확인하여 옮깁니다. 옮길 때 흰색 / 붉은색 / 파란색인지에 따라 동작을 다르게 합니다.
구현(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
143
144
145
|
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Piece{
int y;
int x;
int d;
bool isBottom;
};
int n, k;
int mat[15][15];
vector<int> state[15][15];
Piece ps[15];
int dir[5][2] = {{0,0}, {0,1}, {0,-1}, {-1,0}, {1,0}};
bool isValid(int y, int x){
return (y>=1 && y<=n) && (x>=1 && x<=n);
}
// 흰색으로 이동
void go_white(int cy, int cx, int ny, int nx){
if(state[ny][nx].size() != 0) ps[state[cy][cx][0]].isBottom = false;
for(int i=0; i<state[cy][cx].size(); i++){
state[ny][nx].push_back(state[cy][cx][i]);
int num = state[cy][cx][i];
ps[num].y = ny;
ps[num].x = nx;
}
state[cy][cx].clear();
}
// 붉은색으로 이동
void go_red(int cy, int cx, int ny, int nx){
ps[state[cy][cx][0]].isBottom = false;
reverse(state[cy][cx].begin(), state[cy][cx].end());
for(int i=0; i<state[cy][cx].size(); i++){
state[ny][nx].push_back(state[cy][cx][i]);
int num = state[cy][cx][i];
ps[num].y = ny;
ps[num].x = nx;
}
state[cy][cx].clear();
for(int i=1; i<state[ny][nx].size(); i++) ps[state[ny][nx][i]].isBottom = false;
ps[state[ny][nx][0]].isBottom = true;
}
// 파란색으로 이동
void go_blue(int cy, int cx, int cd){
int nd;
if(cd==1) nd=2;
else if(cd==2) nd=1;
else if(cd==3) nd=4;
else if(cd==4) nd=3;
ps[state[cy][cx][0]].d = nd;
int ny = cy + dir[nd][0];
int nx = cx + dir[nd][1];
if(isValid(ny, nx)){
if(mat[ny][nx] == 0) go_white(cy, cx, ny, nx);
else if(mat[ny][nx] == 1) go_red(cy, cx, ny, nx);
}
}
// 4개 이상이 쌓였는지 확인
bool check(){
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
if(state[i][j].size() >= 4) return true;
}
}
return false;
}
void solution(){
int ans = 0;
while(true){
if(check()){
cout << ans << endl;
return;
}
if(ans > 1000){
cout << -1 << endl;
return;
}
for(int i=1; i<=k; i++){
if(!ps[i].isBottom) continue;
int cy = ps[i].y;
int cx = ps[i].x;
int cd = ps[i].d;
int ny = cy + dir[cd][0];
int nx = cx + dir[cd][1];
if(mat[ny][nx]==2 || !isValid(ny, nx)) go_blue(cy, cx, cd);
else if(mat[ny][nx]==0) go_white(cy, cx, ny, nx);
else if(mat[ny][nx]==1) go_red(cy, cx, ny, nx);
}
ans ++;
}
}
int main(void){
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> n >> k;
for(int i=1; i<=n; i++){
for(int j=1; j<=n; j++){
cin >> mat[i][j];
}
}
int a,b,c;
for(int i=1; i<=k; i++){
cin >> a >> b >> c;
ps[i] = {a, b, c, true};
state[a][b].push_back(i);
}
solution();
}
|
cs |
시행착오
반응형
'코딩 공부 > 백준' 카테고리의 다른 글
[백준][C++] 13460 구슬 탈출 2 (0) | 2021.04.10 |
---|---|
[백준][C++] 1445 일요일 아침의 데이트 (0) | 2021.04.10 |
[백준][C++] 14464 소가 길을 건너간 이유 4 (0) | 2021.04.05 |
[백준][C++] 1826 연료 채우기 (0) | 2021.04.05 |
[백준][C++] 2406 안정적인 네트워크 (0) | 2021.04.05 |