土豪聪要请客(题解)

土豪聪要请客

试题描述
众所周知,聪哥(ndsf)是个土豪,不过你们不知道的是他的MZ和他的RMB一样滴多……
某天土豪聪又赚了10^10000e的RMB,他比较开心,于是准备请客。他在自己在XX星上的别墅里面大摆酒席,想要邀请尽可能多的MZ来参加他的宴会。他将会同MZ一起坐在一个巨大的长方形桌子上。这个桌子能坐下的人数等于他的边长。聪哥要求他的桌子能够放进他的别墅,并且桌子的边必须与别墅的边界平行。给定别墅的平面图,请你求出聪哥最多可以请多少个MZ。
输入
第一行n,m。表示别墅的长宽
下面n行,每行m个字符,表示一个方块是空的(‘.’)或是被占用了(‘X’)。
聪哥只要他的桌子放在别墅里,并且桌子不能占用任何一个已经占用了的方块。
输出
一个数,表示聪哥最多可以请几个Maze。
输入示例1
2 2
..
..

输出示例1

7

输入示例2

4 5
..X..
.X...
X....
.....

输出示例2

11

上一题是CZY的MZ,这题变成聪哥的了……

先明确一下题意,智商捉急的我看了半天样例才理解:地图中选一个周长最大的只包含字符‘.’的矩形,使矩形周长最大,答案是这个最大的周长-1.

我的思路是这样的:枚举上下边界,于是可以把二维的地图压缩成一维的(只要当前列有障碍物X就压成一个‘X’,没有就压成一个‘.’,如样例2地图中,当前枚举到2~4行,那么压缩后的地图变为“XX...”)。压缩成一维后,问题转化为“在一个只包含字符X和字符.的字符串中,选一个尽量长的只包含字符‘.’的连续子串”,因为是连续的,左右端点构成一个滑动窗口,可以用“尺取法”(个人习惯的叫法,详见代码)解决。



#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std;

int read() {
    int x = 0, f = 1; char c = getchar();
    while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
    while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
    return x * f;
}

#define maxn 410
#define INF 1073741823
int n, m, l, r, ans, S[maxn][maxn];
char Map[maxn][maxn];
bool can[maxn];

int main() {
    n = read(); m = read();
    for(int i = 1; i <= n; i++) scanf("%s", Map[i] + 1);
    
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++)
            S[i][j] = S[i-1][j] + (Map[i][j] == 'X');
    for(int i = 1; i <= n; i++)
        for(int j = i; j <= n; j++) {
            memset(can, 0, sizeof(can));
            for(int k = 1; k <= m; k++) can[k] = !(S[j][k] - S[i-1][k]);
            l = 1; int tmp = -INF;
            for(r = 1; r <= m; r++) if(!can[r]) l = r + 1;
            else tmp = max(tmp, r - l + 1);
            ans = max(ans, (tmp + j - i + 1 << 1) - 1);
        }
    
    printf("%d\n", ans);
    
    return 0;
}

 

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/4926194.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值