1018번: 체스판 다시 칠하기 (acmicpc.net)
#문제 간단 정리
문제 상황: 지민이는 MxN 크기의 보드를 발견했습니다. 이 보드는 검은색(B)과 흰색(W)의 정사각형으로 구성되어 있습니다. 지민이는 이 보드에서 8x8 크기의 체스판 부분을 잘라내고 싶습니다.
조건: 체스판의 규칙에 따라 각 칸은 검은색과 흰색으로 번갈아가면서 칠해져야 합니다. 체스판의 맨 왼쪽 위 칸의 색깔에 따라 두 가지 색칠 방식이 있습니다.
목표: 8x8 크기로 잘라낸 부분에서 체스판 규칙에 얼마나 많이 위배되는지 확인하고, 최소 몇 개의 정사각형을 다시 칠해야 하는지 결정하는 프로그램을 작성해야 합니다.
#문제 해결 방법
목적: 이 코드는 주어진 보드에서 8x8 크기의 체스판을 찾아서, 체스판의 첫 번째 칸이 'W' 또는 'B'로 시작할 때 각각 몇 개의 사각형을 다시 그려야 하는지 계산하고, 그 중 최소값을 출력합니다.
변수 및 자료구조 설명:
- board[50][50]: 전체 보드를 나타내는 2차원 문자 배열입니다.
- N, M: 보드의 크기를 나타내는 변수로, N은 행의 수, M은 열의 수입니다.
- ansPoint: 8x8 체스판을 그릴 때 필요한 최소 수정 횟수를 저장하는 벡터입니다.
함수 설명:
- makeChessBoard(int startX, int startY, int N, int M): 시작점 (startX, startY)에서 8x8 크기의 체스판을 그리기 위해 필요한 최소 수정 횟수를 반환합니다.
- 체스판의 첫 번째 칸이 'W'로 시작하는 경우와 'B'로 시작하는 경우에 대해 각각 계산하여 더 작은 값을 반환합니다.
메인 프로그램 설명:
- 입출력 속도 향상을 위한 설정을 합니다.
- 보드의 크기 N과 M을 입력받습니다.
- 보드의 각 칸에 대한 값을 입력받아 board에 저장합니다.
- 모든 위치에서 8x8 크기의 체스판을 그릴 수 있는지 확인하고, 가능한 경우 makeChessBoard 함수를 호출하여 필요한 최소 수정 횟수를 계산하고, ansPoint 벡터에 추가합니다.
- ansPoint 벡터를 오름차순으로 정렬하고, 첫 번째 원소 (즉, 가장 작은 값)을 출력합니다.
#전체 코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
char board[50][50];
int N, M;
vector<int> ansPoint;
int makeChessBoard(int startX, int startY,int N, int M) {
int ansCount1 = 0;
int ansCount2 = 0;
int n = startX + 8;
int m = startY + 8;
if (n > N || m > M) {
return 123456789;
}
for (int i = startX; i < n; i++) {
for (int j = startY; j < m; j++) {
// 0 0이 W인경우
if ((i - startX) % 2 == 0 && (j - startY) % 2 == 0) {
if (board[i][j] == 'B') ansCount1++;
}
if ((i - startX) % 2 == 0 && (j - startY) % 2 != 0) {
if (board[i][j] == 'W') ansCount1++;
}
if ((i - startX) % 2 != 0 && (j - startY) % 2 != 0) {
if (board[i][j] == 'B') ansCount1++;
}
if ((i - startX) % 2 != 0 && (j - startY) % 2 == 0) {
if (board[i][j] == 'W') ansCount1++;
}
//0 0이 B 인경우
if ((i - startX) % 2 == 0 && (j - startY) % 2 == 0) {
if (board[i][j] == 'W') ansCount2++;
}
if ((i - startX) % 2 == 0 && (j - startY) % 2 != 0) {
if (board[i][j] == 'B') ansCount2++;
}
if ((i - startX) % 2 != 0 && (j - startY) % 2 != 0) {
if (board[i][j] == 'W') ansCount2++;
}
if ((i - startX) % 2 != 0 && (j - startY) % 2 == 0) {
if (board[i][j] == 'B') ansCount2++;
}
}
}
return(ansCount1 > ansCount2 ? ansCount2 : ansCount1);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int N, M;
cin >> N >> M;
for (int i = 0; i < N; i++) {
string input; cin >> input;
for (int j = 0; j < M; j++) {
board[i][j] = input[j];
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
int ans = makeChessBoard(i, j,N,M);
if (ans != 123456789) {
ansPoint.push_back(ans);
}
}
}
sort(ansPoint.begin(), ansPoint.end());
cout << ansPoint.front();
return 0;
}
#후기
훨씬더 간단한 해결책이 있다...
바로 정답 체스판을 가져와서 비교하는 방법이다.
어쩌면 이렇게 간단한 풀이법이 묘미일지도 모른다
더 간단한 해결한 블로그 링크
[백준 / BOJ] - 1018번 체스판 다시 칠하기 C++ 풀이 :: Just Give Me The Code (tistory.com)
'[백준] > C++' 카테고리의 다른 글
백준 7576번 토마토 [C++] (0) | 2023.09.14 |
---|---|
백준 7562번 나이트의 이동 [C++] (0) | 2023.09.14 |
백준 2178번 미로 탐색[C++] (0) | 2023.09.06 |
백준 9252번 LCS 2 [C++] (0) | 2023.09.03 |
백준 1260번 DFS와BFS [C++] (0) | 2023.08.30 |