[暴力]餐桌

题目描述

你家刚买了一套新房,想邀请朋友回来庆祝,所以需要一个很大的举行餐桌,餐桌能容纳的人数等于餐桌的周长,你想买一个能容纳最多人的餐桌,餐桌的边必须跟房间的边平行。
给你的房间的设计,计算最多能邀请的客人数。

Input

第一行包含两个整数R和C(1<=R,C<=2000),表示房子的长和宽。
接下来R行每行S个字符(中间没有空格),“.”表示空白区域,“X”表示有障碍物,餐桌所占区域必须是空白的。

Output

输出最多能要求的客人数量。

Sample Input

输入1:
2 2
..
..

输入2:
4 4
X.XX
X..X
..X.
..XX

输入3:
3 3
X.X
.X.
X.X

Sample Output

输出1:
7

输出2:
9

输出3:
3

Data Constraint

Hint

【数据规模】
50%的数据R,C<=400
70%的数据R,C<=1000
100%的数据,R,C<=2000

分析

这题相当奇妙,其实只用搞一个前缀和然后暴力枚举开始点,然后取最大值(具体为什么不超时我也不知道,我也很难讲清,看程序吧)
时间复杂度分摊:O(kn^2)(k是数据中横向间隔的最大数)

#include <iostream>
#include <cstdio>
#define rep(i,a,b) for (i=a;i<=b;i++)
using namespace std;
int r,c;
int f[2001][2001];
void init()
{
    int i,j;
    char q;
    scanf("%d%d",&r,&c);
    rep(i,1,r)
    rep(j,1,c)
    {
        do
        {
            scanf("%c",&q);
        }
        while (q!='.'&&q!='X');
        if (q!='X') f[i][j]=f[i-1][j]+1;
    }
}
void doit()
{
    int i,j,k,s,ans=0;
    rep(i,1,r)
    rep(j,1,c)
    {
        s=f[i][j];
        k=j+1;
        while (f[i][k]!=0&&k<=c)
        {
            ans=max(ans,(s+k-j)*2-1);
            s=min(s,f[i][k]);
            k++;
        }
        ans=max(ans,(s+k-j)*2-1);
    }
    printf("%d",ans);
}
int main()
{
    init();
    doit();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值