백준 1018(체스판 다시 칠하기)

jh Seo·2022년 6월 17일
2

백준

목록 보기
6/180

개요

[링크]백준 1018번: 체스판 다시 칠하기

nxm크기의 타일에 색이 아무렇게나 칠해져있다.
8x8사이즈로 자르고 타일의 색을 바꿔서 체스판을 만들 때
타일의 색을 최소 횟수로 변경하는 수는?

접근 방식

  • 처음 방식
    일단 nxm의 타일의 (0,0)에서 (n-8,m-8)까지의
    각 좌표에서, 오른쪽으로 8칸 밑으로 8칸 설정한 후
    설정된 8x8 체스판에서 타일을 얼마나 변경해야하는지
    조사하려고 했다.

    그러나 각 8x8체스판의 좌측상단이 검정인지 하양인지에
    따라서 조사해보니 틀리다고 나왔다.
    이유는 좌측 상단을 바꿔야하는 경우도 있기 때문이였다.

  • 두번째 방식
    그래서 코드의 양은 많아지지만 복붙만 하면 되서
    각 8x8체스판의 좌측 상하단, 우측 상하단을 다 조사해줬다.

두 번째 방식 코드(틀린 코드)

2차원 char 배열을 동적 할당하고, 입력값을 받는 input()함수,

nxm의 타일에서 (0,0)부터 (n-8,m-8)까지 좌표값을 checkboard함수에 넣어주고 비교해서
타일 변경 최솟값 갱신하는 solution()함수

넘어온 좌표값에서 오른쪽 8칸 밑으로 8칸 바꿔야할 타일 수 조사하는 checkboard함수로 이루어져 있다.

#include<iostream>					

using namespace std;

char** arr;
void solution(const int& N,const int& M);

void input() {										//입력값받고 배열 동적할당해주는 함수
	int N = 0, M = 0;
	cin >> N >> M;
	arr = new char* [N];
	for (int i = 0; i < N; i++) {
		arr[i] = new char[M];
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++)
			cin >> arr[i][j];
	}
	solution(N, M);
}

int checkBoard(const int& x,const int& y) {			//입력 좌표값에서 오른쪽 8칸,밑 8칸씩 체크하고 몇개 바꿔야하는지 return하는 함수
													//입력값으로 받아온 (x,y)좌표에서 8x8 사각형 범위에서 좌측 상하단 우측상하단이 검정인지 하양인지 
													//총 8번 비교하는 함수

	int	wrongTile = 64;								//각 네 귀퉁이에서 조사했을때 제일 적게 색바꾸는 수. return값이다.

	if (arr[x][y] == 'B')														//x,y가 검정일 때(좌측 상단)
	{
		int tempWrongTile = 0;													//각 케이스에서 임시로 저장하는 타일수
		for (int i = x; i < x+8; i++) {
			for (int j = y; j < y+8; j++) {
				if (i % 2 != 0 && j % 2 != 0 && arr[i][j]!='B') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 검은색이여야함.
				}
				else if (i % 2 != 0 && j % 2 == 0 && arr[i][j] !='W') {			//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if (i % 2 == 0 && j % 2 != 0 && arr[i][j] != 'W') {		//행이 짝수고 열이 홀수면
					tempWrongTile++;											//흰색이여야함.
				}
				else if (i % 2 == 0 && j % 2 == 0 && arr[i][j] != 'B') {		//행 짝 열 짝
					tempWrongTile++;											//검정이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;		//비교해서 wrongTile값에 넣기
	}
	else if (arr[x][y] == 'W')													//x,y가 흰색일때(좌측 상단)
	{
		int tempWrongTile = 0;	
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if (i % 2 != 0 && j % 2 != 0 && arr[i][j] != 'W') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if (i % 2 != 0 && j % 2 == 0&& arr[i][j] != 'B') {			//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 검정색이여야함.
				}
				else if (i % 2 == 0 && j % 2 != 0&& arr[i][j] != 'B') {			//행이 짝수고 열이 홀수면
					tempWrongTile++;											//검정색이여야함.
				}
				else if (i % 2 == 0 && j % 2 == 0&& arr[i][j] != 'W') {			//행 짝 열 짝
					tempWrongTile++;											//흰색이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	if (arr[x + 7][y] == 'B') {													//(x+7,y)값이 검정색일 때(좌측 하단)
		int tempWrongTile = 0;
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if (i % 2 != 0 && j % 2 != 0 && arr[i][j] != 'W') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if (i % 2 != 0 && j % 2 == 0 && arr[i][j] != 'B') {		//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 검정색이여야함.
				}
				else if (i % 2 == 0 && j % 2 != 0 && arr[i][j] != 'B') {		//행이 짝수고 열이 홀수면
					tempWrongTile++;											//검정색이여야함.
				}
				else if (i % 2 == 0 && j % 2 == 0 && arr[i][j] != 'W') {		//행 짝 열 짝
					tempWrongTile++;											//흰색이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	else if (arr[x + 7][y] == 'W') {										//(x+7,y)값이 흰색일 때(좌측 하단)
		int tempWrongTile = 0;
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if (i % 2 != 0 && j % 2 != 0 && arr[i][j] != 'B') {			//행과 열이 홀수면 
					tempWrongTile++;										//타일은 검은색이여야함.
				}
				else if (i % 2 != 0 && j % 2 == 0&& arr[i][j] != 'W') {		//행이 홀수고 열이 짝수면
					 tempWrongTile++;										//타일은 흰색이여야함.
				}
				else if (i % 2 == 0 && j % 2 != 0&& arr[i][j] != 'W') {		//행이 짝수고 열이 홀수면
					tempWrongTile++;										//흰색이여야함.
				}
				else if (i % 2 == 0 && j % 2 == 0&& arr[i][j] != 'B') {		//행 짝 열 짝
					tempWrongTile++;										//검정이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	if (arr[x][y+7] == 'B') {												//(x,y+7)값이 검정색일 때(우측 상단)
		int tempWrongTile = 0;
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if (i % 2 != 0 && j % 2 != 0&& arr[i][j] != 'W') {			//행과 열이 홀수면 
					 tempWrongTile++;										//타일은 흰색이여야함.	
				}
				else if (i % 2 != 0 && j % 2 == 0&& arr[i][j] != 'B') {		//행이 홀수고 열이 짝수면
					tempWrongTile++;										//타일은 검정색이여야함.
				}
				else if (i % 2 == 0 && j % 2 != 0&& arr[i][j] != 'B') {		//행이 짝수고 열이 홀수면
					 tempWrongTile++;										//검정색이여야함.
				}
				else if (i % 2 == 0 && j % 2 == 0&& arr[i][j] != 'W') {		//행 짝 열 짝
					 tempWrongTile++;										//흰색이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	else if (arr[x][y+7] == 'W') {												//(x,y+7)값이 흰색일 때(우측 상단)
		int tempWrongTile = 0;
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if (i % 2 != 0 && j % 2 != 0 && arr[i][j] != 'B') {			//행과 열이 홀수면 
					 tempWrongTile++;										//타일은 검은색이여야함.
				}
				else if (i % 2 != 0 && j % 2 == 0&& arr[i][j] != 'W') {		//행이 홀수고 열이 짝수면
					 tempWrongTile++;										//타일은 흰색이여야함.
				}
				else if (i % 2 == 0 && j % 2 != 0&& arr[i][j] != 'W') {		//행이 짝수고 열이 홀수면
					tempWrongTile++;										//흰색이여야함.
				}
				else if (i % 2 == 0 && j % 2 == 0&& arr[i][j] != 'B') {		//행 짝 열 짝
					tempWrongTile++;										//검정이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	if (arr[x + 7][y+7] == 'B') {											//(x+7,y+7)값이 검정색일 때(우측 하단)
		int tempWrongTile = 0;
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if (i % 2 != 0 && j % 2 != 0 && arr[i][j] != 'B') {			//행과 열이 홀수면 
					 tempWrongTile++;										//타일은 검은색이여야함.
				}
				else if (i % 2 != 0 && j % 2 == 0 && arr[i][j] != 'W') {	//행이 홀수고 열이 짝수면
					tempWrongTile++;										//타일은 흰색이여야함.
				}
				else if (i % 2 == 0 && j % 2 != 0&& arr[i][j] != 'W') {		//행이 짝수고 열이 홀수면
					 tempWrongTile++;										//흰색이여야함.
				}
				else if (i % 2 == 0 && j % 2 == 0&& arr[i][j] != 'B') {		//행 짝 열 짝
					 tempWrongTile++;										//검정이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	else if (arr[x + 7][y + 7] == 'W') {									//(x+7,y+7)값이 흰색일 때(우측 하단)
		int tempWrongTile = 0;
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if (i % 2 != 0 && j % 2 != 0 && arr[i][j] != 'W') {			//행과 열이 홀수면 
					 tempWrongTile++;										//타일은 흰색이여야함.
				}
				else if (i % 2 != 0 && j % 2 == 0&& arr[i][j] != 'B') {		//행이 홀수고 열이 짝수면
					 tempWrongTile++;										//타일은 검정색이여야함.
				}
				else if (i % 2 == 0 && j % 2 != 0&& arr[i][j] != 'B') {		//행이 짝수고 열이 홀수면
					 tempWrongTile++;										//검정색이여야함.
				}
				else if (i % 2 == 0 && j % 2 == 0&& arr[i][j] != 'W') {		//행 짝 열 짝
					 tempWrongTile++;										//흰색이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	return wrongTile;
}

void solution(const int& N,const int& M) {	//답 출력 함수
	int minColor = 2500;					//최소로 색칠해야하는 갯수
	for (int i = 0; i < N - 7; i++) {		//(i,j)칸에서 오른쪽으로 8칸 밑으로 8칸 체크해야하니
		for (int j = 0; j < M - 7; j++) {	//n-7,m-7까지 조사
			int check = checkBoard(i, j);
			minColor=check>minColor? minColor:check;
		}
	}
	cout << minColor;

}

int main() {
	input();
}

하지만 이런 방식으로 풀려하니 틀렸습니다가 떴다.
하루종일 고민하고 백준 질문 게시판을 뒤졌으나
반례조차 모르겠어서 백준에 질문을 해서
반례를 얻어내었다.

[링크] 백준에 올린 질문

이 반례를 토대로 분석해본 결과,
checkboard에서 8x8의 타일을 조사할 때,
아무 생각없이 좌측상단의 타일을
(0,0)으로 여기고 풀었었다.

(x,y)의 좌표값을 받아왔으니
당연히 8x8타일의 좌측 상단은 (x,y)인데
(0,0)으로 생각하고 좌측 상단은 짝수,짝수로
이미 정하고 풀어서 만약 x나 y가 홀수가 들어오면
틀리는 것이였다.

그래서 해결법은 그냥
checkboard안의

i % 2 != 0 && j % 2 != 0&& arr[i][j] != 'W'

이런 비교 구문들을

(i-x) % 2 != 0 && (j-y) % 2 != 0 && arr[i][j] != 'W')

이런식으로 x와 y를 빼주면 된다.

두번째 방식 코드 (수정된 것)

#include<iostream>					

using namespace std;

char** arr;
void solution(const int& N,const int& M);

void input(int&N, int& M) {										//입력값받고 배열 동적할당해주는 함수

	cin >> N >> M;
	arr = new char* [N];
	for (int i = 0; i < N; i++) {
		arr[i] = new char[M];
	}
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++)
			cin >> arr[i][j];
	}
	solution(N, M);
}

int checkBoard(const int& x,const int& y) {			//입력 좌표값에서 오른쪽 8칸,밑 8칸씩 체크하고 몇개 바꿔야하는지 return하는 함수
													//입력값으로 받아온 (x,y)좌표에서 8x8 사각형 범위에서 좌측 상하단 우측상하단이 검정인지 하양인지 
													//총 8번 비교하는 함수

	int	wrongTile = 64;								//각 네 귀퉁이에서 조사했을때 제일 적게 색바꾸는 수. return값이다.

	if (arr[x][y] == 'B')														//x,y가 검정일 때(좌측 상단)
	{
		int tempWrongTile = 0;													//각 케이스에서 임시로 저장하는 타일수
		for (int i = x; i < x+8; i++) {
			for (int j = y; j < y+8; j++) {
				if ((i-x) % 2 != 0 && (j-y) % 2 != 0 && arr[i][j]!='B') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 검은색이여야함.
				}
				else if ((i-x) % 2 != 0 && (j-y) % 2 == 0 && arr[i][j] !='W') {			//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if ((i-x) % 2 == 0 && (j-y) % 2 != 0 && arr[i][j] != 'W') {		//행이 짝수고 열이 홀수면
					tempWrongTile++;											//흰색이여야함.
				}
				else if ((i-x) % 2 == 0 && (j-y) % 2 == 0 && arr[i][j] != 'B') {		//행 짝 열 짝
					tempWrongTile++;											//검정이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;		//비교해서 wrongTile값에 넣기
	}
	else if (arr[x][y] == 'W')													//x,y가 흰색일때(좌측 상단)
	{
		int tempWrongTile = 0;	
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if ((i-x) % 2 != 0 && (j-y) % 2 != 0 && arr[i][j] != 'W') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if ((i-x) % 2 != 0 && (j-y) % 2 == 0&& arr[i][j] != 'B') {			//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 검정색이여야함.
				}
				else if ((i-x) % 2 == 0 && (j-y) % 2 != 0&& arr[i][j] != 'B') {			//행이 짝수고 열이 홀수면
					tempWrongTile++;											//검정색이여야함.
				}
				else if ((i-x) % 2 == 0 && (j-y) % 2 == 0&& arr[i][j] != 'W') {			//행 짝 열 짝
					tempWrongTile++;											//흰색이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	if (arr[x + 7][y] == 'B') {													//(x+7,y)값이 검정색일 때(좌측 하단)
		int tempWrongTile = 0;
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if ((i-x) % 2 != 0 && (j-y) % 2 != 0 && arr[i][j] != 'W') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if ((i-x) % 2 != 0 && (j-y) % 2 == 0 && arr[i][j] != 'B') {		//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 검정색이여야함.
				}
				else if ((i-x) % 2 == 0 && (j-y) % 2 != 0 && arr[i][j] != 'B') {		//행이 짝수고 열이 홀수면
					tempWrongTile++;											//검정색이여야함.
				}
				else if ((i-x) % 2 == 0 && (j-y) % 2 == 0 && arr[i][j] != 'W') {		//행 짝 열 짝
					tempWrongTile++;											//흰색이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	else if (arr[x + 7][y] == 'W') {										//(x+7,y)값이 흰색일 때(좌측 하단)
		int tempWrongTile = 0;													//각 케이스에서 임시로 저장하는 타일수
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if ((i - x) % 2 != 0 && (j - y) % 2 != 0 && arr[i][j] != 'B') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 검은색이여야함.
				}
				else if ((i - x) % 2 != 0 && (j - y) % 2 == 0 && arr[i][j] != 'W') {			//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 != 0 && arr[i][j] != 'W') {		//행이 짝수고 열이 홀수면
					tempWrongTile++;											//흰색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 == 0 && arr[i][j] != 'B') {		//행 짝 열 짝
					tempWrongTile++;											//검정이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;		//비교해서 wrongTile값에 넣기
	}
	if (arr[x][y+7] == 'B') {												//(x,y+7)값이 검정색일 때(우측 상단)
		int tempWrongTile = 0;
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if ((i - x) % 2 != 0 && (j - y) % 2 != 0 && arr[i][j] != 'W') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if ((i - x) % 2 != 0 && (j - y) % 2 == 0 && arr[i][j] != 'B') {			//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 검정색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 != 0 && arr[i][j] != 'B') {			//행이 짝수고 열이 홀수면
					tempWrongTile++;											//검정색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 == 0 && arr[i][j] != 'W') {			//행 짝 열 짝
					tempWrongTile++;											//흰색이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	else if (arr[x][y+7] == 'W') {												//(x,y+7)값이 흰색일 때(우측 상단)
		int tempWrongTile = 0;													//각 케이스에서 임시로 저장하는 타일수
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if ((i - x) % 2 != 0 && (j - y) % 2 != 0 && arr[i][j] != 'B') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 검은색이여야함.
				}
				else if ((i - x) % 2 != 0 && (j - y) % 2 == 0 && arr[i][j] != 'W') {			//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 != 0 && arr[i][j] != 'W') {		//행이 짝수고 열이 홀수면
					tempWrongTile++;											//흰색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 == 0 && arr[i][j] != 'B') {		//행 짝 열 짝
					tempWrongTile++;											//검정이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;		//비교해서 wrongTile값에 넣기
	}
	if (arr[x + 7][y+7] == 'B') {											//(x+7,y+7)값이 검정색일 때(우측 하단)
		int tempWrongTile = 0;													//각 케이스에서 임시로 저장하는 타일수
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if ((i - x) % 2 != 0 && (j - y) % 2 != 0 && arr[i][j] != 'B') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 검은색이여야함.
				}
				else if ((i - x) % 2 != 0 && (j - y) % 2 == 0 && arr[i][j] != 'W') {			//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 != 0 && arr[i][j] != 'W') {		//행이 짝수고 열이 홀수면
					tempWrongTile++;											//흰색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 == 0 && arr[i][j] != 'B') {		//행 짝 열 짝
					tempWrongTile++;											//검정이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;		//비교해서 wrongTile값에 넣기
	}
	else if (arr[x + 7][y + 7] == 'W') {									//(x+7,y+7)값이 흰색일 때(우측 하단)
		int tempWrongTile = 0;
		for (int i = x; i < x + 8; i++) {
			for (int j = y; j < y + 8; j++) {
				if ((i - x) % 2 != 0 && (j - y) % 2 != 0 && arr[i][j] != 'W') {				//행과 열이 홀수면 
					tempWrongTile++;											//타일은 흰색이여야함.
				}
				else if ((i - x) % 2 != 0 && (j - y) % 2 == 0 && arr[i][j] != 'B') {			//행이 홀수고 열이 짝수면
					tempWrongTile++;											//타일은 검정색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 != 0 && arr[i][j] != 'B') {			//행이 짝수고 열이 홀수면
					tempWrongTile++;											//검정색이여야함.
				}
				else if ((i - x) % 2 == 0 && (j - y) % 2 == 0 && arr[i][j] != 'W') {			//행 짝 열 짝
					tempWrongTile++;											//흰색이여야함
				}
			}
		}
		wrongTile = wrongTile > tempWrongTile ? tempWrongTile : wrongTile;
	}
	return wrongTile;
}

void solution(const int& N,const int& M) {	//답 출력 함수
	int minColor = 2500;					//최소로 색칠해야하는 갯수
	for (int i = 0; i < N - 7; i++) {		//(i,j)칸에서 오른쪽으로 8칸 밑으로 8칸 체크해야하니
		for (int j = 0; j < M - 7; j++) {	//n-7,m-7까지 조사
			int check = checkBoard(i, j);
			minColor=check>minColor? minColor:check;
		}
	}
	cout << minColor;

}

int main() {
	int N = 0, M = 0;
	input(N,M);

	for (int i = 0; i < N; i++) {
		delete[] arr[i];
	}
	delete[] arr;
}

다른 방식

[링크] 간단히 푸는 방법
인터넷을 뒤지다 보니 어떤 분(ljm1923)이 올리신
더 쉽게 풀어놓은 방식이 있었다

#include <iostream>
using namespace std;

char map[51][51];

// 왼쪽 위가 B로 시작할 경우
char ans_B[8][8] = { {'B','W','B','W','B','W','B','W'},
					 {'W','B','W','B','W','B','W','B'},
					 {'B','W','B','W','B','W','B','W'},
					 {'W','B','W','B','W','B','W','B'},
					 {'B','W','B','W','B','W','B','W'},
					 {'W','B','W','B','W','B','W','B'},
					 {'B','W','B','W','B','W','B','W'},
					 {'W','B','W','B','W','B','W','B'},
};

// 왼쪽 위가 W로 시작할 경우
char ans_W[8][8] = { {'W','B','W','B','W','B','W','B'},
					 {'B','W','B','W','B','W','B','W'},
					 {'W','B','W','B','W','B','W','B'},
					 {'B','W','B','W','B','W','B','W'},
					 {'W','B','W','B','W','B','W','B'},
					 {'B','W','B','W','B','W','B','W'},
					 {'W','B','W','B','W','B','W','B'},
					 {'B','W','B','W','B','W','B','W'},
};

int N, M;
int min_n = 999;
int cnt_B, cnt_W;
int ans;

void find_mini(int x, int y) {
	
	cnt_B = 0, cnt_W = 0;
    
	int y_i = 0;
	for (int i = y; i < y + 8; i++) {
		int x_i = 0;
		for (int j = x; j < x + 8; j++, x_i++) {
			
			if (map[i][j] != ans_B[y_i][x_i]) cnt_B++;	// map이 왼쪽위가 B인 체스판의 i,j위치와 같지않다면 cnt_B를 ++ 시킨다.
			if (map[i][j] != ans_W[y_i][x_i]) cnt_W++;  // map이 왼쪽위가 W인 체스판의 i,j위치와 같지않다면 cnt_W를 ++ 시킨다.
		}
		y_i++;
	}
    
    // 왼쪽위가 B일 case가 W일때보다 바꿀값이 적다면 B
	if (cnt_B < cnt_W) ans = cnt_B;
	else ans = cnt_W; // 아니라면 W
    
	if (ans < min_n) min_n = ans;  

}

int main() {

	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N >> M;
    
    // 맵 넣기
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < M; j++) {
			cin >> map[i][j];
		}
	}
    // 각 위치에 대하여 체스판 만들기
	for (int i = 0; i <= N - 8; i++) {
		for (int j = 0; j <= M - 8; j++) {
			find_mini(j,i);
		}
	}

    // min 값 출력
	cout << min_n << endl;

	return 0;
}

이런 식으로 좌측 상하단/ 우측 상하단이 B,W일때
총 8번 비교가 아니라,
애초에 체스판에서 나올 수 있는 두가지 경우를
미리 선언해주고
8x8타일로 나눈 후 미리 선언한 두가지 경우와 비교해주는
방법이다. 이게 더 코드도 짧고 보기도 쉬운 것 같다.

문풀후생

x,y로 받아와놓고 좌측 상단은 무조건 (0,0)이여서
짝수,짝수로 단정지어버리는 실수 덕에
너무 오래 시간을 들여 고민을 했다.
더 차분히 생각하자.

profile
코딩 창고!

1개의 댓글

comment-user-thumbnail
2022년 6월 20일

오늘은 코드가 엄청길다. 코드의길이만큼 고민의시간도 흘러갔겠지!? 그모든 시간들은 후에 어떤 방식으로든 너에게 보답할거야. 앞이안보여도 조금만 더 힘내자!☺️

답글 달기