728x90
[SW Expert Academy] 4615번: 재미있는 오셀로 게임 -C++
만날 백준 문제만 풀다가 오랜만에 코딩 외출을 했다.
사실 며칠 전에 풀어봤었는데, 맞는 거 같은데 반례도 모르겠고.. 자꾸 통과가 안 돼서 접었다가 오늘 다시 새 마음가짐으로 다시 짰더니 통과했다. 로직 자체는 같은데..
코드가 백준에서 풀던 것들에서 비해 길다..!
근데 찬찬히 살펴보면 쉽게 풀었다. 그리고 오늘 안 사실인데 SWEA에서는 std::tie()
를 사용할 수 없다. std
멤버가 아닌 tie
를 호출한다며 컴파일에 실패한다. 그래서 직접 pair
를 생성해 받아주었다.
쓴 함수들과 enum
값에 대해 살펴보겠다.
- solve 함수
- 각 테스트케이스마다 실질적으로 게임을 진행하고 결과를 출력하는 함수이다.
- 각 테스트케이스마다
game
함수를 호출한다.
- game 함수
- 게임판(\(board\)) 크기를 설정하며 초기 백돌 두 개와 흑돌 두 개를 놓는 등 초기화 작업을 한다.
- \(m\) 번 돌을 두며 돌을 둘 때마다
put
함수를 호출한다.
- put 함수
- 입력된 위치에 돌을 둔다.
- 상, 하, 좌, 우, 좌상, 우상, 좌하, 우하 총 8방향에 대해 뒤집을 수 있는 돌을 찾고, 돌을 뒤집는다.
- enum BOARD_STATE
- \(board\)의 각각의 셀의 상태를 나타낸다.
- 돌이 놓이지 않은 곳은 \(-1\)
- 흑돌이 놓인 곳은 \(0\)
- 백돌이 놓인 곳은 \(1\)
- 둘이 2개임을 나타내기 위해 STATE_LENGTH를 사용했으며, 아래 코드를 보면 입력 값(1, 2)에 대해 적절한 돌의 색(0, 1)과 반대색(1, 0)을 나타내기 위해 사용했다.
뭔가 글로 쓰니까 더 복잡한 것 같다.
아 그리고 예전에 한참 실패했을 때 깨달은 것인데 아래의 사진과 같이 입출력 예제가 주어진다.
난 당연히 출력 때 "0 16"이나 "1 0 16"과 같은 꼴이면 되는 줄 알았는데... "#1 0 16"으로 '#'까지 붙여야 한다는 것에 놀랐다... 어쩌면 당연히 '#'을 붙여야 하는 것이기는 한데.. 암튼..!
아래는 결국 오늘 통과한 코드다. 예제는.. 없다..
돌을 직접 두면서 돌을 둘 때마다 출력하는 코드를 중간에 삽입해 확인해보는 정도로만 테스트해봤다.
#include <iostream>
#include <vector>
enum BOARD_STATE {
STATE_NONE = -1,
STATE_BLACK, // 0
STATE_WHITE, // 1
STATE_LENGTH // 2
};
void solve(void);
int main(void)
{
std::ios::sync_with_stdio(false);
std::cin.tie(NULL);
solve();
}
void put(std::vector<std::vector<BOARD_STATE>>& board, int x, int y, int color)
{
int length = board.size();
x--; y--;
const BOARD_STATE opposite_color = BOARD_STATE(color % STATE_LENGTH);
const BOARD_STATE current_color = BOARD_STATE((color + 1) % STATE_LENGTH);
board[y][x] = current_color;
// 상, 하 좌, 우, 좌상, 우상, 좌하, 우하
int dx_arr[] = {0, 0, -1, 1, -1, 1, -1, 1};
int dy_arr[] = {-1, 1, 0, 0, -1, -1, 1, 1};
for (int t = 0; t < 8; t++)
{
int dx = dx_arr[t];
int dy = dy_arr[t];
int curr_x = x;
int curr_y = y;
std::vector<std::pair<int, int>> list;
while (0 <= curr_x + dx && curr_x + dx < length
&& 0 <= curr_y + dy && curr_y + dy < length)
{
curr_x += dx; curr_y += dy;
if (STATE_NONE == board[curr_y][curr_x]) break;
if (opposite_color == board[curr_y][curr_x])
{
list.push_back(std::make_pair(curr_x, curr_y));
continue;
}
for (int i = 0; i < list.size(); i++)
{
int lx, ly;
lx = list[i].first; ly = list[i].second;
board[ly][lx] = current_color;
}
break;
}
}
}
std::pair<int, int> game(std::vector<std::vector<BOARD_STATE>>& board, int total_count)
{
int length = board.size();
int mid = length / 2;
board[mid][mid] = board[mid - 1][mid - 1] = STATE_WHITE;
board[mid][mid - 1] = board[mid - 1][mid] = STATE_BLACK;
for (int count = 0; count < total_count; count++)
{
int x, y, c;
std::cin >> x >> y >> c;
put(board, x, y, c);
}
int white_count, black_count;
white_count = black_count = 0;
for (int i = 0; i < length; i++)
for (int j = 0; j < length; j++)
{
if (STATE_WHITE == board[i][j])
white_count++;
if (STATE_BLACK == board[i][j])
black_count++;
}
return std::make_pair(black_count, white_count);
}
void solve(void)
{
int test_case;
std::cin >> test_case;
for (int t = 1; t <= test_case; t++)
{
int n, m;
std::cin >> n >> m;
std::vector<std::vector<BOARD_STATE>> board(n, std::vector<BOARD_STATE>(n, STATE_NONE));
std::pair<int, int> count = game(board, m);
std::cout << "#" << t << " " << count.first << " " << count.second << '\n';
}
}
잘못된 점이나 부족한 점 지적해주시면 감사하겠습니다
728x90
'algorithm > SW Expert Academy' 카테고리의 다른 글
[SWEA] 1225번: 7일차 - 암호생성기 -C++ (0) | 2021.01.26 |
---|