본문 바로가기

algorithm/SW Expert Academy

[SWEA] 4615번: 재미있는 오셀로 게임 -C++

728x90

[SW Expert Academy] 4615번: 재미있는 오셀로 게임 -C++

SW Expert Academy

 

SW Expert Academy

SW 프로그래밍 역량 강화에 도움이 되는 다양한 학습 컨텐츠를 확인하세요!

swexpertacademy.com

만날 백준 문제만 풀다가 오랜만에 코딩 외출을 했다.

사실 며칠 전에 풀어봤었는데, 맞는 거 같은데 반례도 모르겠고.. 자꾸 통과가 안 돼서 접었다가 오늘 다시 새 마음가짐으로 다시 짰더니 통과했다. 로직 자체는 같은데..

ㅜㅜ

 


코드가 백준에서 풀던 것들에서 비해 길다..!

 

근데 찬찬히 살펴보면 쉽게 풀었다. 그리고 오늘 안 사실인데 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