문제링크
문제
8*8크기의 체스판에 왕이 하나 있다. 킹의 현재 위치가 주어진다. 체스판에서 말의 위치는 다음과 같이 주어진다. 알파벳 하나와 숫자 하나로 이루어져 있는데, 알파벳은 열을 상징하고, 숫자는 행을 상징한다. 열은 가장 왼쪽 열이 A이고, 가장 오른쪽 열이 H까지 이고, 행은 가장 아래가 1이고 가장 위가 8이다. 예를 들어, 왼쪽 아래 코너는 A1이고, 그 오른쪽 칸은 B1이다.
킹은 다음과 같이 움직일 수 있다.
- R : 한 칸 오른쪽으로
- L : 한 칸 왼쪽으로
- B : 한 칸 아래로
- T : 한 칸 위로
- RT : 오른쪽 위 대각선으로
- LT : 왼쪽 위 대각선으로
- RB : 오른쪽 아래 대각선으로
- LB : 왼쪽 아래 대각선으로
체스판에는 돌이 하나 있는데, 돌과 같은 곳으로 이동할 때는, 돌을 킹이 움직인 방향과 같은 방향으로 한 칸 이동시킨다. 아래 그림을 참고하자.
입력으로 킹이 어떻게 움직여야 하는지 주어진다. 입력으로 주어진 대로 움직여서 킹이나 돌이 체스판 밖으로 나갈 경우에는 그 이동은 건너 뛰고 다음 이동을 한다.
킹과 돌의 마지막 위치를 구하는 프로그램을 작성하시오.
입력
첫째 줄에 킹의 위치, 돌의 위치, 움직이는 횟수 N이 주어진다. 둘째 줄부터 N개의 줄에는 킹이 어떻게 움직여야 하는지 주어진다. N은 50보다 작거나 같은 자연수이고, 움직이는 정보는 위에 쓰여 있는 8가지 중 하나이다.
출력
첫째 줄에 킹의 마지막 위치, 둘째 줄에 돌의 마지막 위치를 출력한다.
풀이
킹과 돌이 겹치는지, 킹이나 돌이 판 밖으로 나가는지 확인해주는 함수를 미리 만들어두었다.
먼저 돌과 겹치는지 확인한다.
1-1 돌과 겹친다면 돌과 킹이 움직였을 때 판 안에 있는지 확인하고 없다면 생략한다.
1-2 돌과 겹친다면 돌과 킹이 움직였을 때 판 안에 있는지 확인하고 있다면 움직인다.
1-3 돌과 겹치지 않는다면 킹이 움직였을 때 판 안에 있는지 확인하고 없다면 생략한다.
1-4 돌과 겹치지 않는다면 킹이 움직였을 때 판 안에 있는지 확인하고 있다면 움직인다.
코드
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
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
#include <iostream>
using namespace std;
int board[8][8];
// 왕은 1 돌은 2
string king, stone, m;
int n, kingX, kingY, stoneX, stoneY;
// 판 밖으로 나가는지 확인
bool valid(int x, int y) {
if (x > 7 || y > 7 || x < 0 || y < 0) {
return false;
}
return true;
}
// 돌과 겹치는지 확인
bool over(int x, int y) {
// 겹치면
if (board[x][y] == 2) {
return true;
}
return false;
}
int main() {
cin >> king >> stone >> n;
kingX = 7 - (king[1] - '1'); //왕의 x좌표
kingY = king[0] - 'A'; // 왕의 y좌표
stoneX = 7 - (stone[1] - '1'); // 돌의 x좌표
stoneY = stone[0] - 'A'; //돌의 y좌표
board[7-(king[1] - '1')][king[0] - 'A'] = 1;
board[7-(stone[1] - '1')][stone[0] - 'A'] = 2;
for (int i = 0; i < n; i++) {
cin >> m;
if (m == "R") {
// 돌과 겹칠 때
if (over(kingX, kingY + 1)) {
// 킹이나 돌이 판 밖으로 나가는지 확인 -> continue
if (!valid(kingX, kingY + 1) || !valid(stoneX, stoneY + 1)) continue;
// 둘다 나가지 않으면 움직임
else {
board[kingX][kingY] = 0;
board[kingX][kingY + 1] = 1;
board[stoneX][stoneY] = 0;
board[stoneX][stoneY + 1] = 2;
kingY = kingY + 1;
stoneY = stoneY + 1;
}
}
// 돌과 겹치지 않을 때
else {
// 킹이 판 밖으로 나가는지 확인 -> continue
if (!valid(kingX, kingY + 1)) continue;
// 나가지 않으면 움직임
else {
board[kingX][kingY] = 0;
board[kingX][kingY + 1] = 1;
kingY = kingY + 1;
}
}
}
else if (m == "L") {
if (over(kingX, kingY - 1)) {
if (!valid(kingX, kingY - 1) || !valid(stoneX, stoneY - 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX][kingY - 1] = 1;
board[stoneX][stoneY] = 0;
board[stoneX][stoneY - 1] = 2;
kingY = kingY - 1;
stoneY = stoneY - 1;
}
}
else {
if (!valid(kingX, kingY - 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX][kingY - 1] = 1;
kingY = kingY - 1;
}
}
}
else if (m == "B") {
if (over(kingX + 1, kingY)) {
if (!valid(kingX + 1, kingY) || !valid(stoneX + 1, stoneY)) continue;
else {
board[kingX][kingY] = 0;
board[kingX + 1][kingY] = 1;
board[stoneX][stoneY] = 0;
board[stoneX + 1][stoneY] = 2;
kingX = kingX + 1;
stoneX = stoneX + 1;
}
}
else {
if (!valid(kingX + 1, kingY)) continue;
else {
board[kingX][kingY] = 0;
board[kingX + 1][kingY] = 1;
kingX = kingX + 1;
}
}
}
else if (m == "T") {
if (over(kingX - 1, kingY)) {
if (!valid(kingX - 1, kingY) || !valid(stoneX - 1, stoneY)) continue;
else {
board[kingX][kingY] = 0;
board[kingX - 1][kingY] = 1;
board[stoneX][stoneY] = 0;
board[stoneX - 1][stoneY] = 2;
kingX = kingX - 1;
stoneX = stoneX - 1;
}
}
else {
if (!valid(kingX - 1, kingY)) continue;
else {
board[kingX][kingY] = 0;
board[kingX - 1][kingY] = 1;
kingX = kingX - 1;
}
}
}
else if (m == "RT") {
if (over(kingX - 1, kingY + 1)) {
if (!valid(kingX - 1, kingY + 1) || !valid(stoneX - 1, stoneY + 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX - 1][kingY + 1] = 1;
board[stoneX][stoneY] = 0;
board[stoneX - 1][stoneY + 1] = 2;
kingX = kingX - 1;
stoneX = stoneX - 1;
kingY = kingY + 1;
stoneY = stoneY + 1;
}
}
else {
if (!valid(kingX - 1, kingY + 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX - 1][kingY + 1] = 1;
kingX = kingX - 1;
kingY = kingY + 1;
}
}
}
else if (m == "LT") {
if (over(kingX - 1, kingY - 1)) {
if (!valid(kingX - 1, kingY - 1) || !valid(stoneX - 1, stoneY - 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX - 1][kingY - 1] = 1;
board[stoneX][stoneY] = 0;
board[stoneX - 1][stoneY - 1] = 2;
kingX = kingX - 1;
stoneX = stoneX - 1;
kingY = kingY - 1;
stoneY = stoneY - 1;
}
}
else {
if (!valid(kingX - 1, kingY - 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX - 1][kingY - 1] = 1;
kingX = kingX - 1;
kingY = kingY - 1;
}
}
}
else if (m == "RB") {
if (over(kingX + 1, kingY + 1)) {
if (!valid(kingX + 1, kingY + 1) || !valid(stoneX + 1, stoneY + 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX + 1][kingY + 1] = 1;
board[stoneX][stoneY] = 0;
board[stoneX + 1][stoneY + 1] = 2;
kingX = kingX + 1;
stoneX = stoneX + 1;
kingY = kingY + 1;
stoneY = stoneY + 1;
}
}
else {
if (!valid(kingX + 1, kingY + 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX + 1][kingY + 1] = 1;
kingX = kingX + 1;
kingY = kingY + 1;
}
}
}
else if (m == "LB") {
if (over(kingX + 1, kingY - 1)) {
if (!valid(kingX + 1, kingY - 1) || !valid(stoneX + 1, stoneY - 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX + 1][kingY - 1] = 1;
board[stoneX][stoneY] = 0;
board[stoneX + 1][stoneY - 1] = 2;
kingX = kingX + 1;
stoneX = stoneX + 1;
kingY = kingY - 1;
stoneY = stoneY - 1;
}
}
else {
if (!valid(kingX + 1, kingY - 1)) continue;
else {
board[kingX][kingY] = 0;
board[kingX + 1][kingY - 1] = 1;
kingX = kingX + 1;
kingY = kingY - 1;
}
}
}
}
cout << (char)(kingY + 'A') << 8 - kingX <<'\n';
cout << (char)(stoneY + 'A') << 8 - stoneX;
}
|
cs |
메모
코드가 굉장히 길긴 하지만 조금씩 예외 케이스를 찾는 능력이 올라가는 것 같아서 기분이 좋다.
+추가로 코드가 너무 길어서 조금 더 효율적인 풀이 방법으로 풀어보았다.
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
|
#include<iostream>
#include<string>
using namespace std;
#define SIZE 8
string king, stone;
int N;
// R, L, B, T, RT, LT, RB, LB
int dx[SIZE] = { 0, 0, 1, -1, -1, -1, 1, 1 };
int dy[SIZE] = { 1, -1, 0, 0, 1, -1, 1, -1 };
int main(void)
{
int kx, ky, sx, sy;
string direction;
cin >> king >> stone;
for (int i = 0; i < 2; i++)
{
if (i == 0)
{
ky = king[i] - 'A';
sy = stone[i] - 'A';
}
else
{
kx = '8' - king[i];
sx = '8' - stone[i];
}
}
cin >> N;
int dir = 0;
for (int i = 0; i < N; i++)
{
cin >> direction;
if (direction == "R") dir = 0;
else if (direction == "L") dir = 1;
else if (direction == "B") dir = 2;
else if (direction == "T") dir = 3;
else if (direction == "RT") dir = 4;
else if (direction == "LT") dir = 5;
else if (direction == "RB") dir = 6;
else if (direction == "LB") dir = 7;
int kmx = kx + dx[dir];
int kmy = ky + dy[dir];
if (kmx < 0 || kmx >= SIZE || kmy < 0 || kmy >= SIZE) continue;
if (kmx == sx && kmy == sy)
{
int smx = sx + dx[dir];
int smy = sy + dy[dir];
if (smx < 0 || smx >= SIZE || smy < 0 || smy >= SIZE) continue;
sx = smx; sy = smy;
}
kx = kmx; ky = kmy;
}
cout << (char)(ky + 'A') << SIZE - kx << '\n';
cout << (char)(sy + 'A') << SIZE - sx << '\n';
return 0;
}
|
cs |