-

[삼성SW테스트] 백준 17837번 - 새로운 게임 2 (정답률 46%) 본문

1-1. 삼성 SW 테스트

[삼성SW테스트] 백준 17837번 - 새로운 게임 2 (정답률 46%)

asdklfjlasdlfkj 2020. 1. 19. 17:37

https://www.acmicpc.net/problem/17837

 

17837번: 새로운 게임 2

재현이는 주변을 살펴보던 중 체스판과 말을 이용해서 새로운 게임을 만들기로 했다. 새로운 게임은 크기가 N×N인 체스판에서 진행되고, 사용하는 말의 개수는 K개이다. 말은 원판모양이고, 하나의 말 위에 다른 말을 올릴 수 있다. 체스판의 각 칸은 흰색, 빨간색, 파란색 중 하나로 색칠되어있다. 게임은 체스판 위에 말 K개를 놓고 시작한다. 말은 1번부터 K번까지 번호가 매겨져 있고, 이동 방향도 미리 정해져 있다. 이동 방향은 위, 아래, 왼쪽, 오른쪽

www.acmicpc.net

삼성 SW테스트 기출문제다. (유형: 시뮬레이션)

 

삼성 SW테스트는 조건을 많이 주고 조건대로 꼼꼼히 답안을 내는 것을 요구하는 시뮬레이션 유형의 문제를 빈출하는 것 같다. 경사로 문제 (백준 14890번 - https://www.acmicpc.net/problem/14890) 를 제외한 27개의 삼성SW 테스트 기출문제를 풀고나서 느낀 점이다..

 

아무튼 이 문제는 주어진 말판에서 말들이 순차적으로 움직이는데 규칙을 준수하며 이동하는 것을 구현하라는 시뮬레이션 문제다. 다음 말판이 하얀색인 경우, 빨간색인 경우와, 양쪽이 파란색으로 막혀 현재 말의 방향만 바꾸는 경우, 다음이 파란색인데 반대쪽이 하얀색인 경우, 다음이 파란색인데 반대쪽이 빨간색인 경우에 대한 구현을 하면 된다.

 

아래는 소스 코드(C++, 0ms/0.5s)

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
#include <iostream>
#include <vector>
#define maxN 12+2
 
using namespace std;
 
int color[maxN][maxN];
int N, K;
int X, Y, D;
int answer = -1;
typedef struct dir{
    int dr, dc;
}dir;
dir direction[4= { { 01 }, { 0-1 }, { -10 }, { 10 } };
typedef struct chess{
    int no, r, c, d;
}chess;
vector<chess> chess_info[maxN][maxN];
 
int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
 
    cin >> N >> K;
    for (int r = 1; r <= N; r++){
        for (int c = 1; c <= N; c++){
            cin >> color[r][c];
        }
    }
    for (int r = 0; r <= N + 1; r++) color[r][0= 2;
    for (int r = 0; r <= N + 1; r++) color[r][N + 1= 2;
    for (int c = 0; c <= N + 1; c++) color[0][c] = 2;
    for (int c = 0; c <= N + 1; c++) color[N + 1][c] = 2;
    // 외곽까지 모든 색 입력 완료.
 
    for (int k = 0; k < K; k++){
        cin >> X >> Y >> D;
        chess a;
        a.no = k + 1;
        a.r = X;
        a.c = Y;
        a.d = D - 1;
        chess_info[X][Y].push_back(a);
    }
    // 체스말 입력 완료.
    int Time = 0;
    while (Time <= 1000){
        Time++;
        for (int cur_chess = 1; cur_chess <= K; cur_chess++){
            int cur_chess_r, cur_chess_c, cur_chess_idx, cur_chess_d;
            int n_r, n_c, o_r, o_c;
            int if_found = false;
            for (int r = 1; r <= N; r++){
                for (int c = 1; c <= N; c++){
                    for (int idx = 0; idx < chess_info[r][c].size(); idx++){
                        if (cur_chess == chess_info[r][c][idx].no){
                            cur_chess_r = r;
                            cur_chess_c = c;
                            cur_chess_idx = idx;
                            cur_chess_d = chess_info[r][c][idx].d;
                            if_found = true;
                            break;
                        }
                    }
                    if (if_found) break;
                }
                if (if_found) break;
            }
            n_r = cur_chess_r + direction[cur_chess_d].dr;
            n_c = cur_chess_c + direction[cur_chess_d].dc;
            o_r = cur_chess_r - direction[cur_chess_d].dr;
            o_c = cur_chess_c - direction[cur_chess_d].dc;
            // 1. 양쪽 다 파란색이라면 방향만 바꾼다.
            if (color[n_r][n_c] == 2 && color[o_r][o_c] == 2){
                if (cur_chess_d == 0)
                    chess_info[cur_chess_r][cur_chess_c][cur_chess_idx].d = 1;
                else if (cur_chess_d == 1)
                    chess_info[cur_chess_r][cur_chess_c][cur_chess_idx].d = 0;
                else if (cur_chess_d == 2)
                    chess_info[cur_chess_r][cur_chess_c][cur_chess_idx].d = 3;
                else if (cur_chess_d == 3)
                    chess_info[cur_chess_r][cur_chess_c][cur_chess_idx].d = 2;
                continue;
            }
            vector<chess> temp;
            for (int idx = cur_chess_idx; idx < chess_info[cur_chess_r][cur_chess_c].size(); idx++){
                temp.push_back(chess_info[cur_chess_r][cur_chess_c][idx]);
            }// 아래에서부터 담아둠.
            // 1. 다음이 흰색
            if (color[n_r][n_c] == 0){
                for (int i = 0; i < temp.size(); i++){
                    chess_info[n_r][n_c].push_back(temp[i]);
                }
                int erase_cnt = temp.size();
                for (int i = 0; i < erase_cnt; i++){
                    chess_info[cur_chess_r][cur_chess_c].pop_back();
                }
                if (chess_info[n_r][n_c].size() >= 4){
                    answer = Time;
                    cout << answer << '\n';
                    return 0;
                }
                temp.clear();
                continue;
            }
            // 2. 다음이 빨간색
            else if (color[n_r][n_c] == 1){
                for (int i = temp.size() - 1; i >= 0; i--) chess_info[n_r][n_c].push_back(temp[i]);
                int erase_cnt = temp.size();
                for (int i = 0; i < erase_cnt; i++) chess_info[cur_chess_r][cur_chess_c].pop_back();
                if (chess_info[n_r][n_c].size() >= 4){
                    answer = Time;
                    cout << answer << '\n';
                    return 0;
                }
                temp.clear();
                continue;
            }
            // 3. 다음이 파란색인데 반대가 하얀색인경우
            else if (color[n_r][n_c] == 2 && color[o_r][o_c] == 0){
                if (cur_chess_d == 0) {
                    temp[0].d = 1;
                }
                else if (cur_chess_d == 1)
                    temp[0].d = 0;
                else if (cur_chess_d == 2) temp[0].d = 3;
                else if (cur_chess_d == 3) temp[0].d = 2;
                int erase_cnt = temp.size();
                for (int i = 0; i < erase_cnt; i++){
                    chess_info[cur_chess_r][cur_chess_c].pop_back();
                }
                for (int i = 0; i < temp.size(); i++){
                    chess_info[o_r][o_c].push_back(temp[i]);
                }
                if (chess_info[o_r][o_c].size() >= 4){
                    answer = Time;
                    cout << answer << '\n';
                    return 0;
                }
                temp.clear();
                continue;
            }
            else if (color[n_r][n_c] == 2 && color[o_r][o_c] == 1){
                if (cur_chess_d == 0) {
                    temp[0].d = 1;
                }
                else if (cur_chess_d == 1)
                    temp[0].d = 0;
                else if (cur_chess_d == 2) temp[0].d = 3;
                else if (cur_chess_d == 3) temp[0].d = 2;
                int erase_cnt = temp.size();
                for (int i = 0; i < erase_cnt; i++){
                    chess_info[cur_chess_r][cur_chess_c].pop_back();
                }
                for (int i = temp.size()-1; i >=0; i--){
                    chess_info[o_r][o_c].push_back(temp[i]);
                }
                if (chess_info[o_r][o_c].size() >= 4){
                    answer = Time;
                    cout << answer << '\n';
                    return 0;
                }
                temp.clear();
                continue;
            }
            // 4. 다음이 파란색이면서 
        } // 이동 완료.
        // 아니면 다음 while
    }
    cout << answer << '\n';
    return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

Comments