首页 > 代码库 > hdu1505City Game

hdu1505City Game

http://acm.hdu.edu.cn/showproblem.php?pid=1505

题意:R为被占位置,F为空位,求出最大子空矩阵大小*3.

思路:1、悬线法,记录每个位置的悬线能到达的左边和右边最远位置。然后维护面积最大值。

每个点计算一次。

这是我第一个扫描法的题,从上由下扫描,up[i][j],le[i][j],r[i][j]表示格子i,j的悬线长度及该悬线向左、向右运动的“运动极限”。

我A的时候没怎么感觉它是扫描线的方法,有点背包的感觉。

#include <iostream>#include <stdio.h>#include <string.h>#include <stdlib.h>using namespace std;int map[1010][1010];int up[1010][1010];int le[1010][1010];int r[1010][1010];int main(){    int T,n,m,sum;    char ch;    scanf("%d",&T);    while(T--)    {        sum=0;        scanf("%d%d",&n,&m);        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)            {                ch=getchar();                while(ch!=F&&ch!=R)                ch=getchar();                map[i][j]=ch==F?1:0;            }        }        int lo,ro;        for(int i=0;i<n;i++)        {            lo=-1;            ro=m;            for(int j=0;j<m;j++)            {                if(map[i][j]==0)                {                    up[i][j]=0;                    le[i][j]=0;                    lo=j;                }                else if(map[i][j]==1)                {                    up[i][j]=i==0?1:up[i-1][j]+1;                    le[i][j]=i==0?lo+1:max(lo+1,le[i-1][j]);                }            }            for(int j=m-1;j>=0;j--)            {                if(map[i][j]==0)                {                    r[i][j]=m;                    ro=j;                }                else                {                    r[i][j]=i==0?ro-1:min(ro-1,r[i-1][j]);                }                 sum=max(sum,up[i][j]*(r[i][j]-le[i][j]+1));            }        }        long long  ans=(long long )sum*3;        printf("%lld\n",ans);    }    return 0;}