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

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


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值