가장 처음에 N×N크기에 사탕을 채워 놓는다. 사탕의 색은 모두 같지 않을 수도 있다. 상근이는 사탕의 색이 다른 인접한 두 칸을 고른다. 그 다음 고른 칸에 들어있는 사탕을 서로 교환한다. 이제, 모두 같은 색으로 이루어져 있는 가장 긴 연속 부분(행 또는 열)을 고른 다음 그 사탕을 모두 먹는다. 사탕이 채워진 상태가 주어졌을 때, 상근이가 먹을 수 있는 사탕의 최대 개수를 구하는 프로그램을 작성하시오.
풀이과정은 다음과 같다.
#include <iostream>
using namespace std;
int N;
char board[50][50];
void swap(int& lhs, int& rhs) {
int temp = lhs;
lhs = rhs;
rhs = temp;
}
int checkLines(int y, int x) {
int retRow = 1, retCol = 1;
char c = board[y][x];
for (int i = x + 1; i < N; ++i) {
if (c == board[y][i]) retRow++;
else break;
}
for (int i = x - 1; i >= 0; --i) {
if (c == board[y][i]) retRow++;
else break;
}
for (int i = y + 1; y < N; ++i) {
if (c == board[i][x]) retCol++;
else break;
}
for (int i = y - 1; y >= 0; --i) {
if (c == board[i][x]) retCol++;
else break;
}
return max(retRow, retCol);
}
int preprocess() {
int ret = 0;
for (int y = 0; y < N; ++y)
for (int x = 0; x < N; ++x)
ret = max(ret, checkLines(y, x));
return ret;
}
int solve() {
// 모든 칸에 대해 오른쪽, 아래쪽만 비교하고 교환해준다.
// 교환해준 다음에는 현재 칸, 바꾼 칸에 대해 행과 열을 검사한다.
int ret = preprocess();
for (int y = 0; y < N; ++y) {
for (int x = 0; x < N; ++x) {
if (x + 1 < N && board[y][x] != board[y][x + 1]) { // 우측 교환
swap(board[y][x], board[y][x + 1]); // 교환해주고, 검사한 뒤,
ret = max(ret, max(checkLines(y, x), checkLines(y, x + 1)));
swap(board[y][x], board[y][x + 1]); // 교환을 해제한다.
}
if (y + 1 < N && board[y][x] != board[y + 1][x]) { // 하단 교환
swap(board[y][x], board[y + 1][x]);
ret = max(ret, max(checkLines(y, x), checkLines(y + 1, x)));
swap(board[y][x], board[y + 1][x]);
}
}
}
return ret;
}
int main() {
ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr);
cin >> N;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
cin >> board[i][j];
cout << solve() << '\n';
}