您的位置:首页 > 其它

HDU 4331Image Recognition2012多校第四场A题(暴力枚举+小技巧)

2013-08-08 09:53 344 查看


Image Recognition

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 906    Accepted Submission(s): 340


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的正方形,寻找four edges全为1的squares。寻找四边全为1的正方形的个数,不是矩形。。rectangle,对于正方形的内部没有要求。题目看错了TAT。
 
           
解题思路:用一个小技巧,因为必须是正方形,所以先统计往四个方向可以延伸的最长的长度,顺便也可以直接把每一个点往对角线上延伸的最长的长度也可以找出来。方便到最后枚举的时候统计个数。

            题目地址:Image
Recognition

AC代码:
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cstdio>
#include<time.h>
#define MAX 1005
using namespace std;
int e[MAX][MAX],w[MAX][MAX],n[MAX][MAX],s[MAX][MAX];
//记录东南西北四个方向能延伸最长的长度
int p1[MAX][MAX],p2[MAX][MAX];
//统计两个对角线能延伸的最长的长度
int map1[MAX][MAX],m; //存放地图的//m记录规模大小

void cal1()   //从左上往右下遍历
{
int i,j;
memset(e,0,sizeof(e));
memset(s,0,sizeof(s));
for(i=1;i<m;i++)
for(j=1;j<m;j++)
{
if(map1[i][j])
{
e[i][j]=e[i][j-1]+1;
s[i][j]=s[i-1][j]+1;
}
p1[i][j]=e[i][j]<s[i][j]?e[i][j]:s[i][j];
}
}

void cal2()   //从右下往左上遍历
{
int i,j;
memset(w,0,sizeof(w));
memset(n,0,sizeof(n));
for(i=m-1;i>0;i--)
for(j=m-1;j>0;j--)
{
if(map1[i][j])
{
w[i][j]=w[i][j+1]+1;
n[i][j]=n[i+1][j]+1;
}
p2[i][j]=w[i][j]<n[i][j]?w[i][j]:n[i][j];
}
}

int main()
{
//clock_t start, finish;
//double  duration;
//start = clock();
int T,cas,i,j,k;
scanf("%d",&T);
for(cas=1;cas<=T;cas++)
{
printf("Case %d: ",cas);
int res=0;
scanf("%d",&m);
m++;
for(i=1;i<m;i++)
for(j=1;j<m;j++)
{
scanf("%d",&map1[i][j]);
if(map1[i][j]) res++;
}

cal1();
cal2();
for(i=1;i<m;i++)
for(j=1;j<m;j++)
{
if(map1[i][j])
{
for(k=2;k<=p2[i][j];k++)  //枚举边长,前面已经统计小正方形
if(p1[i+k-1][j+k-1]>=k)
res++;
}
}

printf("%d\n",res);
}

//finish = clock();
//duration = (double)(finish - start) / CLOCKS_PER_SEC;
//printf( "%f seconds\n", duration );
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: