LA-3029(扫描线)

题意:

给定一个n*m的矩阵,一些格子是空地“F”,一些是障碍"R",找出一个全部由F组成的面积最大的子矩阵;

思路:

对每个格子维护up[i][j],le[i][j],ri[i][j].表示这个格子能向上的最长的长度,这个长度能向左向右移动的最长距离:

面积的最大值就是ans=max(ans ,up[i][j]*(ri[i][j]-le[i][j]+1));

AC代码:

#include <bits/stdc++.h>
using namespace std;

#define For(i,j,n) for(int i=j;i<=n;i++)
#define mst(ss,b) memset(ss,b,sizeof(ss));

typedef  long long LL;

template<class T> void read(T&num) {
    char CH; bool F=false;
    for(CH=getchar();CH<‘0‘||CH>‘9‘;F= CH==‘-‘,CH=getchar());
    for(num=0;CH>=‘0‘&&CH<=‘9‘;num=num*10+CH-‘0‘,CH=getchar());
    F && (num=-num);
}
int stk[70], tp;
template<class T> inline void print(T p) {
    if(!p) { puts("0"); return; }
    while(p) stk[++ tp] = p%10, p/=10;
    while(tp) putchar(stk[tp--] + ‘0‘);
    putchar(‘\n‘);
}

const LL mod=1e9+7;
const double PI=acos(-1.0);
const LL inf=1e18;
const int N=2e5+10;
const int maxn=1005;
const double eps=1e-10;

char mp[maxn][maxn],s[2*maxn];

int up[maxn][maxn],le[maxn][maxn],ri[maxn][maxn],n,m;
int main()
{
        int t;
        read(t);
        while(t--)
        {
            read(n);read(m);
      mst(up,0);
      mst(le,0);
      mst(ri,0);
      For(i,1,n)
      {
        For(j,1,m)
        {
          scanf("%s",s);
          mp[i][j]=s[0];
        }
      }
      For(i,1,n)
      {
          For(j,1,m)
          {
            if(mp[i][j]==‘F‘)up[i][j]= i==1?1:up[i-1][j]+1;
            else up[i][j]=0;
          }
      }
      int ans =0;
      For(i,1,n)
      {
        int lo=0,ro=m+1;
        For(j,1,m)
        {
          if(mp[i][j]==‘F‘)le[i][j]= i==1?lo+1:max(lo+1,le[i-1][j]);
          else le[i][j]=j+1,lo=j;
        }
        for(int j=m;j>0;j--)
        {
          if(mp[i][j]==‘F‘)ri[i][j]= i==1?ro-1:min(ro-1,ri[i-1][j]);
          else ri[i][j]=j-1,ro=j;
        }
        For(j,1,m)
        {
          if(mp[i][j]==‘F‘)ans=max(ans,(ri[i][j]-le[i][j]+1)*up[i][j]);
        }
      }
      cout<<3*ans<<"\n";
        }

        return 0;
}
时间: 2024-09-17 03:55:53

LA-3029(扫描线)的相关文章

LA 3029 - City Game (简单扫描线)

题目链接 题意:给一个m*n的矩阵, 其中一些格子是空地(F), 其他是障碍(R).找一个全部由F 组成的面积最大的子矩阵, 输出其面积乘以3的结果. 思路:如果用枚举的方法,时间复杂度是O(m^2 n^2); 因为不但要枚举每一个点,而且矩阵的大小不知道,所以还要枚举长和宽. 可以通过枚举每一个点,求该点所能构成的最大矩形的边界. 分别用le[], rig[] 和 up[] 表示左边界,右边界和 上边界. 1 #include <iostream> 2 #include <cstrin

la 3029 City Game (扫描法)

题目链接 思路:对每一个格子进行处理:计算包含它的最大矩形. up[i][j]:   存储矩形的高: left[i][j]:  存储矩形的左边界的列号: right[i][j]:存储矩形的右边界的列号. 面积 = up[i][j] * ( right[i][j] - left[i][j] +1 ). 心得:即便是有了思路,写代码前也要在纸上画画,模拟模拟.否则就像代码中提示注意的地方,写成了0,估计debug半天也不知道错在哪了. #include <algorithm> #include &

LA 4127 - The Sky is the Limit (离散化 扫描线 几何模板)

题目链接 非原创 原创地址:http://blog.csdn.net/jingqi814/article/details/26117241 题意:输入n座山的信息(山的横坐标,高度,山底宽度),计算他们的轮廓线, 即露出来的表面边长,有些山是重叠的不计.空白地带不计,每座山都是等腰三角形. 分析:大白书P414页. 求小山的总长度,用一些虚线将其离散化,分成一段一段的,特征点:山脚,山顶,交点.这样就能保 证相邻两个扫描点之间再无交点.然后一最上面的点就是分割点,维护上一个点lastp即可. 1

LA 3905 Meteor 扫描线

The famous Korean internet company nhn has provided an internet-based photo service which allows The famous Korean internet company users to directly take a photo of an astronomical phenomenon in space by controlling a high-performance telescope owne

[USACO18JAN] Lifeguards S (线段树:扫描线面积)

扫描线裸题没什么好说的 注意空间不要开小了!!! 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define N 100100 5 #define ll long long 6 using namespace std; 7 8 int n,ctx; 9 int cnt[N<<3]; 10 ll a[N<<1],sum[N<<3]; 11 struc

hdu1828 Picture (线段树:扫描线周长)

依然是扫描线,只不过是求所有矩形覆盖之后形成的图形的周长. 容易发现,扫描线中的某一条横边对答案的贡献. 其实就是 加上/去掉这条边之前的答案 和 加上/去掉这条边之后的答案 之差的绝对值 然后横着竖着都做一遍就行了 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #define N 10010 5 #define ll long long 6 using namespace std;

bzoj1645 / P2061 [USACO07OPEN]城市的地平线City Horizon(扫描线)

P2061 [USACO07OPEN]城市的地平线City Horizon 扫描线 扫描线简化版 流程(本题为例): 把一个矩形用两条线段(底端点的坐标,向上长度,添加$or$删除)表示,按横坐标排序 $upd:$本题的底端点坐标简化为$(x,0)$ 蓝后对纵坐标建一棵线段树(本题需要对高度进行离散化). 每次对线段树进行覆盖$or$删除区间操作,顺便统计一下$k=$有多少点被覆盖到 而两次(线段)操作之间的长度为$r=x_{i}-x_{i-1}$ 于是两条线段之间被覆盖的面积即为$k*r$ (

【BZOJ】1382: [Baltic2001]Mars Maps (线段树+扫描线)

1382: [Baltic2001]Mars Maps Time Limit: 5 Sec  Memory Limit: 64 MB Description 给出N个矩形,N<=10000.其坐标不超过10^9.求其面积并 Input 先给出一个数字N,代表有N个矩形. 接下来N行,每行四个数,代表矩形的坐标. Output 输出面积并 Sample Input 2 10 10 20 20 15 15 25 30 Sample Output 225 本以为是傻逼题,没想到不容易啊- 线段树+扫描

BZOJ 3022 [Balkan2012]The Best Teams(扫描线+线段树)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3022 [题目大意] 给定n个球员,第i个球员年龄为AGEi,水平为SKILLi. 没有任何两个球员的水平相同.将这些球员按水平排序, 对于一次比赛,你需要选择若干个球员去比赛,但不能同时选择两个水平相邻的球员. m次询问,每次给定a和k,表示要在年龄不超过a的球员中选择不超过k个球员, 请计算skill和的最大值. [题解] 对于询问年龄的限制,我们可以通过扫描线来处理. 我们将所有

【扫描线】Gym - 101190E - Expect to Wait

假设初始人数为0, 将每个时刻在等待的人数写下来,就是求个和. 如果纵坐标看成人数,横坐标看成时间,就是求个面积. 因为初始人数不一定为零,所以离线后扫描线即可回答所有询问. #include<cstdio> #include<algorithm> using namespace std; typedef long long ll; int n,m,e; struct LINE{ int y,l,id; }ls[200010]; bool cmp(const LINE &a