HDU4331 Image Recognition

题目描述:

Problem Description
Now there is an image recognition problem for you. Now you are given an image which is a N * N matrix and there are only 0s and 1s in the matrix. And we are interested in the squares in whose four edges there is no 0s. So it’s your task to find how many such squares in the image.

Input
The first line of the input contains an integer T (1<=T<=10) which means the number of test cases.
For each test cases, the first line is one integer N (1<=N<=1000) which is the size of the image. Then there are N lines and each line has N integers each of which is either 0 or 1.

Output
For each test case, please output a line which is “Case X: Y”, X means the number of the test case and Y means the number of the squares we are interested in in the image.

Sample Input

1
3
1 1 0
1 1 0
0 0 0

Sample Output

Case 1: 5

题目分析:

题目大意是N*N的矩阵,只有0或者1,求这个矩阵中所有边为1的正方形的个数。例如样例的数据,除了4个边长为1的正方形,还有一个边长为2的正方形。(我们要求的正方形只需要四条边为1,内部不需要满足1)
其实我觉得这题暴力能过,但是我发现这个时间就是压着TLE的风险过的,所以其实这道题应该不是暴力题。遍历每个点的上下左右,比较其对应的左上和右下的对顶点。

代码如下:

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;

const int MAXN=1005;

int mp[MAXN][MAXN];
int T,n;
int ans;
int up[MAXN][MAXN];int down[MAXN][MAXN];int lft[MAXN][MAXN];int righ[MAXN][MAXN];
int rightdown[MAXN][MAXN];int leftup[MAXN][MAXN];

int main()
{
    scanf("%d",&T);
    int t=0;
    while(T--)
    {
        t++;
        scanf("%d",&n);
        ans=0;
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                scanf("%d",&mp[i][j]);
                if (mp[i][j]) ans++;
            }
        }
        memset(up,0,sizeof(up));
        memset(down,0,sizeof(down));
        memset(lft,0,sizeof(lft));
        memset(righ,0,sizeof(righ));
        memset(leftup,0,sizeof(leftup));
        memset(rightdown,0,sizeof(rightdown));
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                if (mp[i][j])
                {
                    righ[i][j]=righ[i][j-1]+1;
                    down[i][j]=down[i-1][j]+1;
                }
                rightdown[i][j]=min(righ[i][j],down[i][j]);
            }
        }
        for(int i=n-1; i>=0; i--)
        {
            for(int j=n-1; j>=0; j--)
            {
                if (mp[i][j])
                {
                    lft[i][j]=lft[i][j+1]+1;
                    up[i][j]=up[i+1][j]+1;
                }
                leftup[i][j]=min(lft[i][j],up[i][j]);
            }
        }
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                for(int k=2; k<=leftup[i][j]; k++)
                {
                    if (rightdown[i+k-1][j+k-1]>=k)
                         ans++;
                }
            }
        }
        printf("Case %d: %d\n",t,ans);
    }
    return 0;
}

你可能感兴趣的:(暴力)