기본적으로 이 문제는 M * N 꼴의 인풋을 받아야 하는데 이 부분부터 C++로 해본 경험이 많지 않다. 정렬로 여러 문제를 날먹했기 때문에 이 문제는 단계별로 풀어보려고 한다. 우선 배열을 이용해서 받아서 출력해주는 과정을 가져 보려고 한다. 아래의 코드를 통해서 정상적으로 체스판을 받아들이는 것을 확인했다. 이 체스판을 색칠하는데는 두 가지 방법이 있을 것 같은데 그 중 숫자가 적은 쪽을 선택해서 답으로 출력해주는 과정을 가져 볼 예정이다.
#include "iostream"
using namespace std;
int main(void){
int N, M;
cin >> N >> M;
char arr[N][M];
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j ++){
cin >> arr[i][j];
}
}
cout << "These are the arrays" << "\n";
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j ++){
cout << arr[i][j];
}
cout << "\n";
}
}
위의 과정을 거친 후 해결 방법에 두 가지가 생각이 났다. 첫 번째 해결 방법은 완벽하게 색칠된 두 가지 종류의 체스판을 만든 후 다를 때마다 확인해서 오류를 찾는 방법이고, 두 번째 해결 방법은 첫 번째 것을 기준으로 바꿔야 될 것들을 모두 확인하는 과정이다. 아무래도 두 번째 해결방법이 빅오상 더 좋을 것으로 보이긴 하지만 예외 사항이 많이 생각나서 우선 완벽하게 색칠된 체스판을 구현하는 코드를 생각해서 아래에 구현해 보았다. 참고로 동기가 자꾸 New랑 Delete 사용하라고 구박해서 그 코드도 아래에 후술하겠다.
#include <iostream>
using namespace std;
int main(void){
int N, M, ans[2] = {0};
cin >> N >> M;
char arr[N][M], ans1[N][M], ans2[N][M];
ans1[0][0] = 'B';
ans2[0][0] = 'W';
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j ++){
if (i == 0 && j == 0) continue;
else {
if (j == 0){
if (ans1[i - 1][j] == 'B') ans1[i][j] = 'W';
else ans1[i][j] = 'B';
}
else {
if (ans1[i][j - 1] == 'B') ans1[i][j] = 'W';
else ans1[i][j] = 'B';
}
}
}
}
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j ++){
if (i == 0 && j == 0) continue;
else {
if (j == 0){
if (ans2[i - 1][j] == 'B') ans2[i][j] = 'W';
else ans2[i][j] = 'B';
}
else {
if (ans2[i][j - 1] == 'B') ans2[i][j] = 'W';
else ans2[i][j] = 'B';
}
}
}
}
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j ++){
cout << ans1[i][j];
}
cout << "\n";
}
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j ++){
cout << ans2[i][j];
}
cout << "\n";
}
}
이렇게 코드를 완성하고 나서 비교해주는 코드를 추가하였는데 생각해보니 정답 예시는 하나만 만들면 되었다. 어차피 둘 중 하나인 상황에서 하나의 정답이랑 비교하면 나머지는 N*M에서 값을 뺀 값이기 때문이다... 그래서 ans1만 남기고 코드를 좀 간결하게 고쳐 보았다. 와 근데 보다보니 문제를 잘못 이해했다. 이 중 8 X 8을 추출해야하는 문제인데 나는 그냥 "응 다 비교해"라는 논리로 만들다 보니 코드가 산으로 갔다. 그래도 어떻게든 살리겠다라는 맘으로 이중 for문을 하나 더 삽입해서 코드를 완성하였다.
#include <iostream>
using namespace std;
int main(void){
int N, M, ans = 100000;
cin >> N >> M;
char arr[N][M], ans1[8][8];
ans1[0][0] = 'B';
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j ++){
cin >> arr[i][j];
}
}
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j ++){
if (i == 0 && j == 0) continue;
else {
if (j == 0){
if (ans1[i - 1][j] == 'B') ans1[i][j] = 'W';
else ans1[i][j] = 'B';
}
else {
if (ans1[i][j - 1] == 'B') ans1[i][j] = 'W';
else ans1[i][j] = 'B';
}
}
}
}
for (int ii = 0; ii < N - 7; ii ++){
for (int jj = 0; jj < M - 7; jj ++){
int temp = 0;
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j ++){
if (arr[i + ii][j + jj] != ans1[i][j]) temp ++;
}
}
if (temp > 32) temp = 64 - temp;
if (ans > temp) ans = temp;
}
}
cout << ans;
}
아래의 부분에서 동기가 설명해 준 부분을 추가해보려고 한다. 메모리 초기화가 사이즈가 저장되어 있지 않을 때 나오는 케이스를 이야기하면서 이야기가 나왔는데 이 방법으로 선언하는데 분명한 장점은 있어 보이는데 정확히 알지 못하겠어서 책을 통해서 알게되면 다시 수정해놓겠다.
#include <iostream>
using namespace std;
int main(void){
int N, M, ans = 100000;
cin >> N >> M;
char ans1[8][8];
char **arr = new char*[N];
for (int i = 0; i < N; i++) {
arr[i] = new char[M];
}
ans1[0][0] = 'B';
for (int i = 0; i < N; i++){
for (int j = 0; j < M; j ++){
cin >> arr[i][j];
}
}
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j ++){
if (i == 0 && j == 0) continue;
else {
if (j == 0){
if (ans1[i - 1][j] == 'B') ans1[i][j] = 'W';
else ans1[i][j] = 'B';
}
else {
if (ans1[i][j - 1] == 'B') ans1[i][j] = 'W';
else ans1[i][j] = 'B';
}
}
}
}
for (int ii = 0; ii < N - 7; ii ++){
for (int jj = 0; jj < M - 7; jj ++){
int temp = 0;
for (int i = 0; i < 8; i++){
for (int j = 0; j < 8; j ++){
if (arr[i + ii][j + jj] != ans1[i][j]) temp ++;
}
}
if (temp > 32) temp = 64 - temp;
if (ans > temp) ans = temp;
}
}
cout << ans;
}