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