题解 P4417 【[COCI2006-2007#2] STOL】

评分感觉有点怪,要是数据范围给大点(例如1000)蓝题是刚好的。

提供一个思路,首先枚举桌子左下角的点,然后枚举桌子的长度,预先处理出当前点上面的最接近的墙或者上边界的距离,然后桌子的宽度是左下角的点往右延伸到的点的值取最小。时间复杂度是\(O(n^3)\)

具体实现和其他解释在代码里,如下。

#include<bits/stdc++.h>
using namespace std;
int r,s,wsi[405][405],ans;//wsi数组保存这个点上方最接近的墙或者上边界与该点的距离
char inp;
bool cal[405][405];//保存该点是否是空地
int area(int x,int y){
    int len=2147483647,res=0;
    for(int j=y;j<=s&&cal[x][j];j++){//一直延伸到遇到墙或者右边界
        len=min(len,wsi[x][j]);//宽度对这些点的wsi值取min。
        res=max(res,len*2+(j-y+1)*2);
    }
    return res;
}
int main(){
    cin>>r>>s;
    for(int i=1;i<=r;i++)
        for(int j=1;j<=s;j++){
            cin>>inp;
            if(inp=='.')
                cal[i][j]=1;
        }
    for(int j=1;j<=s;j++){
        int up=0;
        for(int i=1;i<=r;i++){
            if(cal[i][j])//该点是空地?距离值++:距离值=0;
                up++;
            else up=0;
            wsi[i][j]=up;
        }
    }
    for(int i=1;i<=r;i++)
        for(int j=1;j<=s;j++)
            if(cal[i][j])
                ans=max(ans,area(i,j)-1);//ans对以每个点为左下角能够得到的最大周长值取max
    cout<<ans;
}
posted @ 2019-11-01 10:30  Schwarzkopf_Henkal  阅读(161)  评论(0编辑  收藏  举报