반응형
문제
해결 방법
입력값을 기준으로 먼저 체스판의 배치를 배열에 넣어준 뒤, 체스판을 순회하며 해당 자리에 기물이 있다면 그 기물이 갈 수 있는 모든 경로의 좌표를 체크한다. 이를 끝까지 반복하고, 체크되지 않은 좌표의 갯수를 더해 출력한다.
아쉬웠던 점
상하좌우/대각/나이트 이동 코드가 한 45줄 가량 나왔는데 더 줄일 수 있을 것 같다... 더럽다. 또한, 체스판의 크기만큼 반복을 돌리는데 입력할때, 입력을 기반으로 경로 파악할때, 빈칸 체크할때 총 세번이나 돌아간다.
쓰면서 생각났는데 O를 X로 바꿀때(경로 체크할때) + 체스 기물 갯수 하면 마지막에 체크되지 않은 좌표를 찾기위해 순회하는 일은 없어도 됐다... 의미없는 반복이 한번 더 들어갔다.
코드
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
|
#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
bool Chess_Check(string _Board[][8], int _x, int _y)
{
if (_x > 7 || _x < 0 || _y > 7 || _y < 0) return true;
if (_Board[_x][_y] != "X" && _Board[_x][_y] != "O")
return true;
_Board[_x][_y] = "O";
return false;
}
void UDLR(string _Board[][8], int _x, int _y, int IsK = false)
{
for (int i = _x + 1; i < 8; ++i)
if (Chess_Check(_Board, i, _y) || IsK) break;
for (int i = _x - 1; i > -1; --i)
if (Chess_Check(_Board, i, _y) || IsK) break;
for (int i = _y + 1; i < 8; ++i)
if (Chess_Check(_Board, _x, i) || IsK) break;
for (int i = _y - 1; i > -1; --i)
if (Chess_Check(_Board, _x, i) || IsK) break;
}
void Diagonal(string _Board[][8], int _x, int _y, int _Size, bool IsK = false) //
{
if (_Size == 8 || _Size == -1)
{
for (int i = _y + 1; i < 8; ++i)
if (Chess_Check(_Board, _x - (i - _y), i) || IsK) break;
for (int i = _y - 1; i > -1; --i)
if (Chess_Check(_Board, _x + (i - _y), i) || IsK) break;
}
if (_Size == 8 || _Size == 1)
{
for (int i = _y - 1; i > -1; --i)
if (Chess_Check(_Board, _x - (i - _y), i) || IsK) break;
for (int i = _y + 1; i < 8; ++i)
if (Chess_Check(_Board, _x + (i - _y), i) || IsK) break;
}
}
void Knight(string _Board[][8], int _x, int _y)
{
for (int i = -1; i < 2; i += 2)
for (int j = -2; j < 3; j += 4)
{
Chess_Check(_Board, _x + j, _y + i);
Chess_Check(_Board, _x + i, _y + j);
}
}
void Chess(string& _Str)
{
string Board[8][8];
for (int i = 0; i < 8; ++i)
for (int j = 0; j < 8; ++j)
Board[i][j] = "X";
int x = 0, y = 0, ans = 0;
for (auto i : _Str) //1. Board에 체스 기물 배치
{
//숫자라면
if (i >= 48 && i <= 57)
y += i - 49; //-48(char to int) -1(증감)
//영어라면
else if (i != 47)
Board[x][y] = i;
y++;
//줄바꿈
if (y != 8)
continue;
x++;
y = -1;
}
for (int i = 0; i < 8; ++i) //2. Board 순회하며 기물 만나면 이동 가능 경로를 체크함
for (int j = 0; j < 8; ++j)
{
//영어라면
if (Board[i][j] != "O" && Board[i][j] != "X")
{
if (Board[i][j] == "b" || Board[i][j] == "B" || Board[i][j] == "q" || Board[i][j] == "Q")
Diagonal(Board, i, j, 8);
if (Board[i][j] == "r" || Board[i][j] == "R" || Board[i][j] == "q" || Board[i][j] == "Q")
UDLR(Board, i, j);
else if (Board[i][j] == "k" || Board[i][j] == "K")
{
UDLR(Board, i, j, true);
Diagonal(Board, i, j, 8, true);
}
else if (Board[i][j] == "p")
Diagonal(Board, i, j, 1, true);
else if (Board[i][j] == "P")
Diagonal(Board, i, j, -1, true);
else if (Board[i][j] == "n" || Board[i][j] == "N")
Knight(Board, i, j);
}
}
for (int i = 0; i < 8; ++i) //3. board 순회하며 X만나면(경로 체크에 안걸렸다면)답에 1 더해줌.
for (int j = 0; j < 8; ++j)
if (Board[i][j] == "X")
ans++;
cout << ans << "\n";
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
string Str;
while (cin >> Str)
Chess(Str);
}
|
cs |
8x8 배열 Board 선언 -> Board에 체스 기물 배치 -> Board 순회하며 기물 만나면 이동 가능 경로를 체크 -> board 순회하며 X만나면(경로 체크에 안걸렸다면)답에 1 더해줌. 마지막 과정은 확실히 있을 필요가 없다.
잡설 : 이 문제 코드 풀이는 내가 처음이다 ㅎ
반응형
'코딩 > 문제풀이-백준' 카테고리의 다른 글
백준 1052번 - 물병 (C++) (0) | 2021.07.16 |
---|---|
백준 4963번 - 섬의 개수 (C++) (0) | 2021.07.16 |
백준 14499번 - 주사위 굴리기 (C++) (0) | 2021.07.14 |
백준 17413번 - 단어 뒤집기 2 (C++) (0) | 2021.07.09 |
백준 2606번 - 바이러스 (C++) (0) | 2021.07.09 |
댓글