【USACO 3.3】(range)Home on the Range

-----------------Prob------------------

Farmer John grazes his cows on a large, square field N (2 <= N <= 250) miles on a side (because, for some reason, his cows will only graze on precisely square land segments). Regrettably, the cows have ravaged some of the land (always in 1 mile square increments). FJ needs to map the remaining squares (at least 2x2 on a side) on which his cows can graze (in these larger squares, no 1x1 mile segments are ravaged).

Your task is to count up all the various square grazing areas within the supplied dataset and report the number of square grazing areas (of sizes >= 2x2) remaining. Of course, grazing areas may overlap for purposes of this report.

 

----------------Solution----------------

DP

f[i][j]=以i,j为左上角顶点的最大正方形边长

ans[x]=边长为x的正方形个数

初始状态  f=Map

转移方程 f[i][j]=min{f[i+1][j+1],f[i+1][j],f[i][j+1]}+1 | i=n-1...1,j=n-1..1,f[i][j]!=0

统计答案

若 f[i][j]>=2 则 { ans[2]~ans[f[i][j]] }+1

---------------------code------------------

/*
ID:zst_0111
LANG:C++
TASK:range
*/
#include<stdio.h>
#include<stdlib.h>

int f[251][251];
int ans[251];

int min(int x,int y)
{
    return x<y?x:y;
}

int main()
{
    int i,j,k,m,n;
    freopen("range.in","r",stdin);
    freopen("range.out","w",stdout);
   
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++)
            scanf("%1d",&f[i][j]);
    for(i=n-1;i>=1;i--)
        for(j=n-1;j>=1;j--)
        {
            if(f[i][j])
            {
                f[i][j]=min(f[i+1][j+1],min(f[i+1][j],f[i][j+1]))+1;
                for(k=2;k<=f[i][j];k++)
                    ans[k]++;
            }
        }
    /*for(i=1;i<=n;i++,printf("\n"))
        for(j=1;j<=n;j++)
            printf("%3d",f[i][j]);*/
    for(i=2;i<=n;i++)
        if(ans[i])
            printf("%d %d\n",i,ans[i]);
    return 0;
}

posted on 2011-09-06 22:28  青色有角三倍速  阅读(144)  评论(0)    收藏  举报