#1469 : 福字
描述
新年到了,你收到了一副畫。你想找到裏面最大的福字。
一副畫是一個n × n的矩陣,其中每個位置都是一個非負整數。
一個福字被定義成是大小爲 k 的正方形,滿足其中的每個位置上的數都恰好比他的左邊的那個和上邊的那個大1(如果左邊或上邊的那個不存在的話就無此要求)。
比如
1 2 3 2 3 4 3 4 5
就是一個福字。(注意左上角可以是任何非負整數)。
你想找到這個矩陣中最大的福字的大小。
輸入
第一行一個數 n,表示矩陣大小。(n ≤ 1000)
接下來 n 行,每行 n 個數,表示這個矩陣。矩陣中的數在0到108之間。
輸出
一行一個數表示最大的福字的大小。
4 1 2 3 0 2 3 4 0 3 4 5 0 0 0 0 0樣例輸出
3
思路:用到動態規劃,res[i][j]表示以位置i, j爲右下角的正方形最大尺寸是多少。
轉移方程:
當位置i,j元素值恰好比左邊元素大一,比上面元素大一,比左上元素大一的時候,
那麼當前位置的值就是三個正方形尺寸最小值加1。
完整代碼:
#include <stdio.h>
#include <string.h>
#include <algorithm>
const int N = 1010;
using namespace std;
int rec[N][N];
int res[N][N];
int main()
{
int n;
while (~scanf("%d", &n))
{
int ans = 1;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
scanf("%d", rec[i] + j);
for (int i = 0; i < n; i++)
res[i][0] = res[0][i] = 1;
for (int i = 1; i < n; i++)
for (int j = 1; j < n; j++)
{
res[i][j] = 1;
if (rec[i][j] == 1 + rec[i-1][j] &&
rec[i][j] == 1 + rec[i][j-1] &&
rec[i][j] == 2 + rec[i-1][j-1])
{
res[i][j] = min(res[i-1][j], res[i][j-1]);
res[i][j] = min(res[i][j], res[i-1][j-1]) + 1;
ans = max(ans,res[i][j]);
}
}
printf("%d\n", ans);
}
return 0;
}