백준의 체스(1986) 문제이다.

[ 문제 바로가기 ]


[ 문제풀이 ]

1) 주어진 맵에 Knight, Queen, Pawn의 위치가 주어졌을 때, 안전한 칸이 총 몇개인지 찾아야 하는 문제이다.

   Knight는 문제에 나와있는 대로 8칸을 움직일 수 있고, Queen은 가로, 세로, 대각선으로 어디든지 나아갈 수 있지만

   중간에 방해물이 있다면 더 이상 나아가지는 못한다. Pawn은 이 문제에서는 방해물의 역할만 한다.

   본인은 먼저 입력으로 주어지는 K,Q,P의 위치를 맵에서 1, 2, 3 으로 저장해 주었다.

   즉, 맵의 상태를 표시하는 MAP[][] 2차원 배열을 하나 사용하였고, 안전 영역을 저장하기 위해서 State[][] 라는 bool형

   2차원 배열을 사용해주었다. State[a][b] = true의 의미는 "(a, b)는 이미 점령당한 좌표이므로 안전영역이 아니다" 라는

   의미이다.

  

2) 본인은, 맵을 입력받은 후에, Knight와 Queen이 갈 수 있는 모든 곳들을 탐색하면서 State[][] 배열의 상태를 true로 바꿔주었다.

   사실, 이 과정은 Knight와 Queen의 움직임만 제대로 이해했다면 어렵지 않은 부분이고, 소스코드만 참고하더라도 알 수 있으

   므로 구체적인 설명은 생략하겠다.

 

   이후, 마지막으로 맵 전체를 돌면서 State[][] 배열의 상태가 false인 좌표들의 갯수를 Count해서 정답으로 출력해주었다.


[ 소스코드 ]

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
#include<iostream>
#include<cstring>
 
#define endl "\n"
#define MAX 1001
using namespace std;
 
int N, M;
int Queen_Num, Knight_Num, Pawn_Num;
int MAP[MAX][MAX];
bool State[MAX][MAX];
 
int Q_dx[] = { 001-1-1-111 };
int Q_dy[] = { 1-100-11-11 };
 
int K_dx[] = { -2-11221-1-2 };
int K_dy[] = { 1221-1-2-2-1 };
 
void Input()
{
    cin >> N >> M;
    cin >> Queen_Num;
    for (int i = 0; i < Queen_Num; i++)
    {
        int a, b;
        cin >> a >> b;
        MAP[a][b] = 1;    // Queen = 1로 표현
    }
 
    cin >> Knight_Num;
    for (int i = 0; i < Knight_Num; i++)
    {
        int a, b;
        cin >> a >> b;
        MAP[a][b] = 2;    // Knight = 2로 표현
    }
    
    cin >> Pawn_Num;
    for (int i = 0; i < Pawn_Num; i++)
    {
        int a, b; 
        cin >> a >> b;
        MAP[a][b] = 3;    // Pawn = 3으로 표현
    }
}
 
void State_Of_MAP(int x, int y, char C)
{
    if (C == 'Q')
    {
        for (int i = 0; i < 8; i++)
        {
            int nx = x + Q_dx[i];
            int ny = y + Q_dy[i];
 
            while (1)
            {
                if (nx < 1 || ny < 1 || nx > N || ny > M) break;
                if (MAP[nx][ny] != 0break;
 
                State[nx][ny] = true;
                nx = nx + Q_dx[i];
                ny = ny + Q_dy[i];
            }
        }
    }
    else if (C == 'K')
    {
        for (int i = 0; i < 8; i++)
        {
            int nx = x + K_dx[i];
            int ny = y + K_dy[i];
 
            if (nx >= 1 && ny >= 1 && nx <= N && ny <= M)
            {
                if (MAP[nx][ny] == 0) State[nx][ny] = true;
            }
        }
    }
}
 
void Print()
{
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= M; j++)
        {
            if (State[i][j] == truecout << 1 << " ";
            else cout << 0 << " ";
        }
        cout << endl;
    }
}
 
void Make_MAP_State()
{
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= M; j++)
        {
            if (MAP[i][j] == 0continue;
            
            if (MAP[i][j] == 1)
            {
                State[i][j] = true;
                State_Of_MAP(i, j, 'Q');
            }
            else if (MAP[i][j] == 2)
            {
                State[i][j] = true;
                State_Of_MAP(i, j, 'K');
            }
            else if (MAP[i][j] == 3)
            {
                State[i][j] = true;
            }
        }
    }
}
 
int Check_Safe_Area()
{
    int Cnt = 0;
    for (int i = 1; i <= N; i++)
    {
        for (int j = 1; j <= M; j++)
        {
            if (MAP[i][j] == 0 && State[i][j] == false) Cnt++;
        }
    }
    return Cnt;
}
 
void Solution()
{
    Make_MAP_State();
    cout << Check_Safe_Area() << endl;
}
 
void Solve()
{
    Input();
    Solution();
}
 
int main(void)
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
 
    //freopen("Input.txt", "r", stdin);
    Solve();
 
    return 0;
}
cs


'[ BOJ Code ] > # BOJ -' 카테고리의 다른 글

[ 백준 1953 ] 팀배분 (C++)  (4) 2019.02.13
[ 백준 2858 ] 기숙사 바닥 (C++)  (0) 2019.02.12
[ 백준 9177 ] 단어 섞기 (C++)  (0) 2019.02.12
[ 백준 3407 ] 맹세 (C++)  (0) 2019.02.11
[ 백준 2011] 암호코드 (C++)  (0) 2019.02.11

+ Recent posts