求最大的矩形(悬线法)

夏天来了,酷暑~Skyline一行人等去海边赏风景(-_-!!),顺便泡在海里凉爽一下。海里这些人又比赛,看谁能游到离海岸最远…… 

Skyline不管身后的朋友一路穿过了警戒线(汗了……),游啊游啊,路过了朝鲜半岛、日本岛,进入了广阔的太平洋……终于发现了一片伫立着好多不明物体的沙滩……爬上了之后便不省人事地睡了…… 

醒来之后Skyline才发现身边只有沙滩和无数的石柱(难道是又一处外太空生命弄的遗迹……),经过短暂的精神恢复期,Skyline在岛上转了一圈,发现这个小岛是没有被发现过的并且除了自己岛上没有任何可以动的生物,不过在一架无人驾驶的飞机残骸里找到了一个装有pascal、c、c++的本本(这么巧……)一种寂寞的恐惧袭来…… 

我们的Skyline可不想成为野人留在这个荒岛上,他要回到祖国报告这个岛屿的发现(新一代好青年啊~)还有参加NOIP2006……当然有可能的话可以考虑在2008年的时候参加奥运游泳比赛…… 

在他在沙滩的最大一块没有石柱的空地上写出SOS的第7个小时之后……一个国内的OIer用GoogleEarth在太平洋里面发现了大大的“Skyline SOS”……发现了Skyline…… 

Skyline回国之后把他的这个遭遇编成了题目扔给了你,要你在已知长宽的沙滩上找出一块最大的没有石柱的矩形沙滩…… 
 

Input

输入文件island.in的第一行为两个整数m,nm,n,表示沙滩的长和宽。 

接下来mm行,每行nn个字符,’O’表示该块沙滩完好无损,没有石柱,’X’表示该块沙滩已被石柱破坏。(字母O不是数字0) 

输入文件中保证至少有一块沙滩完好无损。 

Output

输出文件island.out仅一行,为一个整数,表示最大沙滩的面积。

Samples

Input Copy
4 5
OXOOO
OOOOX
OOOOO
XOOXX
Output
8

Hint

【数据规模】
对于 30%的数据,有 1m,n301≤m,n≤30;
对于 100%的数据,有 1m,n3001≤m,n≤300;

Source

石光中学 2018年 国庆集训 普及组 day6

Discussions

No more discussions

More>>
 
 
 
我用二维前缀和做的,一开始只是试一试可能会超时,带没想到是还真过了
#include<iostream>
#include<algorithm>
#include<queue> 
using namespace std;
const int maxn=1e3+100;
int a[maxn][maxn];
int sum[maxn][maxn];
char s[maxn];
int main(){
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        scanf("%s",s+1);
        for(int j=1;j<=m;j++){
            if(s[j]=='O'){
                a[i][j]=0;
            }
            else{
                a[i][j]=1;
            }
        } 
    }
    int ma=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            sum[i][j]=a[i][j]+sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]; 
        }
    }//9e4*
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int a=i;a<=n;a++){
                for(int b=j;b<=m;b++){
                    int x1=i,y1=j,x2=a,y2=b;
                    int z=sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1];
                    if(z==0){
                        ma=max(ma,(a-i+1)*(b-j+1));
                    }
                    else{
                        break;
                    }                
                }
            }
        }
    } 
    cout<<ma<<endl;
}

 

 

这个是n^2的正解

#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i=(j);i<=(k);++i)
#define per(i,j,k) for(register int i=(j);i>=(k);--i)
using namespace std;
template<class T> inline void read(T &x)
{
    x=0;
    register char c=getchar();
    register bool f=0;
    while(!isdigit(c))f^=c=='-',c=getchar();
    while(isdigit(c))x=x*10+c-'0',c=getchar();
    if(f)x=-x;
}
const int N=301;
int n,m,l[N][N],r[N][N],u[N][N],ans;
char s[N][N];
int main()
{
    cin>>n>>m;
    rep(i,1,n)
    {
        cin>>s[i]+1;
        rep(j,1,m)
        {
            if(s[i][j]=='X') continue;
            l[i][j]=j;
            r[i][j]=j;
            u[i][j]=1;
        }
    }
    rep(i,1,n)
        rep(j,2,m)
            if(s[i][j]=='O'&&s[i][j-1]=='O')
                l[i][j]=l[i][j-1];
    rep(i,1,n)
        per(j,m-1,1)
            if(s[i][j]=='O'&&s[i][j+1]=='O')
                r[i][j]=r[i][j+1];
    rep(i,1,n)
        rep(j,1,m)
        {
            if(s[i][j]=='X')
                continue;
            if(i>1&&s[i-1][j]=='O')
            {
                l[i][j]=max(l[i][j],l[i-1][j]);
                r[i][j]=min(r[i][j],r[i-1][j]);
                u[i][j]=u[i-1][j]+1;
            }
            ans=max(ans,(r[i][j]-l[i][j]+1)*u[i][j]);
        }
    printf("%d",ans);
    return 0;
}

 

posted @ 2021-02-04 16:37  lipu123  阅读(82)  评论(0编辑  收藏  举报