#include <iostream>
#include <vector>
#include <memory.h>
#include <algorithm>
#define MAX_N 20
using namespace std;
int N, ans = -1;
int board[MAX_N][MAX_N];
// 왼쪽 아래 대각선, 오른쪽 아래 대각선 방향으로만 움직인다.
int dx[2] = { 1, 1 };
int dy[2] = { -1, 1 };
void makeBox(int startX, int startY, int left, int right) {
vector<int> history;
history.push_back(board[startX][startY]);
// 시작점에서 왼쪽으로 left 칸만큼 이동
int cx = startX, cy = startY;
for (int i = 0; i < left; i++) {
int nx = cx + dx[0];
int ny = cy + dy[0];
if (nx < 0 || nx >= N || ny < 0 || ny >= N) return;
// 이미 먹었던 디저트 종류라면 반환
if (find(history.begin(), history.end(), board[nx][ny]) != history.end()) return;
history.push_back(board[nx][ny]);
cx = nx; cy = ny;
}
// 이동한 점에서 오른쪽 아래로 이동
for (int i = 0; i < right; i++) {
int nx = cx + dx[1];
int ny = cy + dy[1];
if (nx < 0 || nx >= N || ny < 0 || ny >= N) return;
// 이미 먹었던 디저트 종류라면 반환
if (find(history.begin(), history.end(), board[nx][ny]) != history.end()) return;
history.push_back(board[nx][ny]);
cx = nx; cy = ny;
}
// 시작점에서 오른쪽 아래로 이동
cx = startX; cy = startY;
for (int i = 0; i < right; i++) {
int nx = cx + dx[1];
int ny = cy + dy[1];
if (nx < 0 || nx >= N || ny < 0 || ny >= N) return;
// 이미 먹었던 디저트 종류라면 반환
if (find(history.begin(), history.end(), board[nx][ny]) != history.end()) return;
history.push_back(board[nx][ny]);
cx = nx; cy = ny;
}
// 이동한 점에서 왼쪽 아래로 이동
// 마지막 이동이므로 left - 1 만큼 이동
for (int i = 0; i < left - 1; i++) {
int nx = cx + dx[0];
int ny = cy + dy[0];
if (nx < 0 || nx >= N || ny < 0 || ny >= N) return;
// 이미 먹었던 디저트 종류라면 반환
if (find(history.begin(), history.end(), board[nx][ny]) != history.end()) return;
history.push_back(board[nx][ny]);
cx = nx; cy = ny;
}
ans = max(ans, (int)history.size());
}
void visitCafes(int startX, int startY, int left, int right) {
for (int i = 1; i <= left; i++) {
for (int j = 1; j <= right; j++) {
makeBox(startX, startY, i, j);
}
}
}
void setCrossLength(int startX, int startY, int& left, int& right) {
// 왼쪽 아래 대각선으로 갈 수 있는 최대 길이
int cx = startX, cy = startY;
while (true) {
int nx = cx + dx[0];
int ny = cy + dy[0];
if (nx < 0 || nx >= N || ny < 0 || ny >= N) break;
left++;
cx = nx; cy = ny;
}
// 오른쪽 아래 대각선으로 갈 수 있는 최대 길이
cx = startX, cy = startY;
while (true) {
int nx = cx + dx[1];
int ny = cy + dy[1];
if (nx < 0 || nx >= N || ny < 0 || ny >= N) break;
right++;
cx = nx; cy = ny;
}
}
void goDessertCafe(int startX, int startY) {
int left = 0, right = 0;
setCrossLength(startX, startY, left, right);
// 대각선을 만들 수 없는 경우
if (left == 0 || right == 0) return;
// 대각선을 만들 수 있는 경우
visitCafes(startX, startY, left, right);
}
int main(int argc, char** argv)
{
cin.tie(NULL);
ios_base::sync_with_stdio(false);
int test_case;
int T;
// freopen("input.txt", "r", stdin);
cin >> T;
for (test_case = 1; test_case <= T; ++test_case)
{
memset(board, 0, sizeof(board));
cin >> N;
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
cin >> board[r][c];
}
}
ans = -1;
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
goDessertCafe(r, c);
}
}
printf("#%d %d\n", test_case, ans);
}
return 0;//정상종료시 반드시 0을 리턴해야합니다.
}
Leave a comment