#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;
}