土豪聪要请客
试题描述
众所周知,聪哥(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; }
时间: 2024-10-13 09:00:33