https://vjudge.net/problem/UVALive-3029

题意:

给出一个只含有F和R字母的矩阵,求出全部为F的面积最大的矩阵并且输出它的面积乘以3。

思路:

求面积最大的子矩阵,可以用扫描线。参考训练指南(orz,虽然并不知道为什么用扫描线)。

对于每一个格子包含F,我们可以把它向上拉成一条悬线,直到上面的格子为R,然后观察这条悬线可以扫到左边与右边的最大距离,那么我们所求的面积就是所有的悬线中 悬线的长度乘以(右边界 - 左边界 + 1)的最大值。

然后,需要计算悬线的长度,用up来表示,那么当这个格子为F时up(i,j) = up(i - 1,j) + 1(i >= 1),up(i,j) = 1,(i == 0);

当这个格子为R时,up(i,j) = 0。

然后,用left数组和right数组维护左右边界的信息:

我们假设lo是当前格子之前的最近的是R的格子,从左往右遍历,那么 lo 的初值是-1,那么当(i,j) 为 F时 ,left(i,j) = max(left(i-1,j),lo + 1),为什么呢,因为当前的悬线如果是包含上一行此列的格子的话,那么就要考虑上一行左边的情况了;

当(i,j)为R时,left(i,j) = 0。

维护右边界的信息同理,不同的是求最小值和从右往左遍历。

!!!:记住一边遍历,一边维护。输入也是坑!

代码:

 #include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std; char a[][];
int up[][],right[][],left[][]; int main()
{
int t; scanf("%d",&t); while(t--)
{
int m,n; memset(a,,sizeof(a));
memset(up,,sizeof(up));
memset(right,,sizeof(right));
memset(left,,sizeof(left)); scanf("%d%d",&m,&n); getchar(); for (int i = ;i < m;i++)
for (int j = ;j < n;j++)
{
char s; s = getchar(); while (s != 'R' && s != 'F') s = getchar(); if (s == 'R') a[i][j] = ;
else a[i][j] = ;
} /*for (int i= 0;i < m;i++)
{
for (int j = 0;j < n;j++) printf("%d",(int)a[i][j]); printf("\n");
}*/ int ans = ; for (int i = ;i < m;i++)
{
for (int j = ;j < n;j++)
{
if (i == )
{
up[i][j] = a[i][j];
}
else
{
if (a[i][j]) up[i][j] = up[i-][j] + ;
else up[i][j] = ;
}
} int lo = -,ro = n; if (i == )
{
for (int j = ;j < n;j++)
{
if (a[i][j] == ) left[i][j] = , lo = j;
else left[i][j] = lo + ;
} for (int j = n - ;j >= ;j--)
{
if (a[i][j] == ) right[i][j] = n, ro = j;
else right[i][j] = ro - ;
} for (int j = ;j < n;j++)
{
int tmp = up[i][j] * (right[i][j] - left[i][j] + ); ans = max(ans,tmp * );
}
}
else
{
for (int j = ;j < n;j++)
{
if (a[i][j] == ) left[i][j] = , lo = j;
else left[i][j] = max(lo + ,left[i-][j]);
} for (int j = n - ;j >= ;j--)
{
if (a[i][j] == ) right[i][j] = n, ro = j;
else right[i][j] = min(ro - ,right[i-][j]);
} for (int j = ;j < n;j++)
{
int tmp = up[i][j] * (right[i][j] - left[i][j] + ); ans = max(ans,tmp * );
}
}
} /*for (int i = 0;i < m;i++)
{
for (int j = 0;j < n;j++)
{
printf("%d %d %d\n",up[i][j],left[i][j],right[i][j]);
}
}*/ printf("%d\n",ans);
} return ;
}

uvalive 3029 City Game的更多相关文章

  1. 【UVALive】3029 City Game(悬线法)

    题目 传送门:QWQ 分析 以前见到过差不多的这题. xhk说是单调栈水题,但我又不会单调栈,于是当时就放下了. 这么久过去了我还是不会用单调栈做这题,用的是悬线法. 非常好写 代码 #include ...

  2. City Game UVALive - 3029(悬线法求最大子矩阵)

    题意:多组数据(国外题好像都这样),每次n*m矩形,F表示空地,R表示障碍 求最大子矩阵(悬线法模板) 把每个格子向上延伸的空格看做一条悬线 以le[i][j],re[i][j],up[i][j]分别 ...

  3. UVALive 6889 City Park 并查集

    City Park 题目连接: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=122283#problem/F Description P ...

  4. 并查集 - UVALive 6889 City Park

    City Park Problem's Link: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=129725 Mean: 在 ...

  5. LA 3029 City Game

    LA 3029 求最大子矩阵问题,主要考虑枚举方法,直接枚举肯定是不行的,因为一个大矩阵的子矩阵个数是指数级的,因此应该考虑先进行枚举前的扫描工作. 使用left,right,up数组分别记录从i,j ...

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

    题目链接 题意:给一个m*n的矩阵, 其中一些格子是空地(F), 其他是障碍(R).找一个全部由F 组成的面积最大的子矩阵, 输出其面积乘以3的结果. 思路:如果用枚举的方法,时间复杂度是O(m^2 ...

  7. UVa LA 3029 City Game 状态拆分,最大子矩阵O(n2) 难度:2

    题目 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_pr ...

  8. UVaLive 3695 City Game (扫描线)

    题意:给定m*n的矩阵,有的是空地有的是墙,找出一个面积最大的子矩阵. 析:如果暴力,一定会超时的.我们可以使用扫描线,up[i][j] 表示从(i, j)向上可以到达的最高高度,left[i][j] ...

  9. UVaLive 6854 City (暴力)

    题意:给定一个 n*m 的矩阵,表示有多少条道路与它相连,其中有一个-1,表示未知,道路只能横着和竖着,求-1处的值. 析:根据题意可知,一个点,与其他周围的四个点都可能相连的,也就是说肯定有共用道路 ...

随机推荐

  1. 如何使用 Weave 网络?- 每天5分钟玩转 Docker 容器技术(63)

    weave 是 Weaveworks 开发的容器网络解决方案.weave 创建的虚拟网络可以将部署在多个主机上的容器连接起来.对容器来说,weave 就像一个巨大的以太网交换机,所有容器都被接入这个交 ...

  2. NPOI office 组件资料汇总 (excel, word)

    POI 是一套用Java写成的库,能够帮助开发者在没有安装微软Office的情况下读写Office 的文件,支持的文件格式包括xls, doc, ppt等. NPOI 是POI的.net 版本. 最新 ...

  3. [2015-10-11]tfs2015 vs2013 配置持续集成

    今天刚配置完tfs2015+vs2013的持续集成(自动构建+自动发布),记录一下走过的坑. tfs2015和tfs build server是之前其他同事装的,略去不讲,列一下几个坑以及埋坑方法. ...

  4. 从服务器端获取列和数据动态创建Ext.grid.EditorGridPanel

    1.添加列的方法 var addColumn = function(){ this.fields = ''; this.columns = ''; this.addColumns=function(n ...

  5. ==与equal

    @ 对象类型比较:(引用类型) ==和equal都表示对象引用的内存地址是否相同 对象类型继承Object并重写方法equal()用于对象的比较 @ 字符串比较: ==表示String引用的内存地址是 ...

  6. Linux的netstat查看端口是否开放见解(0.0.0.0与127.0.0.1的区别)

    linux运维都需要对端口开放查看  netstat 就是对端口信息的查看 # netstat -nltp p 查看端口挂的程序 [root@iz2ze5is23zeo1ipvn65aiz ~]# n ...

  7. Zookeeper的安装的配置

    详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcyt192 安装和配置详解 本文介绍的 Zookeeper 是以 3.2.2 这个 ...

  8. Centos6.6下安装Python3.5

    centos6.6自带的Python2.6,如果想要安装新版本的Python例如Python2.7+或者Python3.5,不能够用yum安装,那么只能从源码编译安装. Step 1: 安装依赖库和编 ...

  9. 基于NIOS-II的示波器:PART1 按键&显示屏驱动&界面

    NIOS II 相关资料以及基础入门 <NiosII的奇幻漂流> <Nios II那些事儿> 本文所有的硬件基础以及工程参考来自魏坤示波仪,重新实现驱动并重构工程. 基于NIO ...

  10. NHibernate教程(8)--巧用组件

    本节内容 引入 方案1:直接添加 方案2:巧用组件 实例分析 结语 引入 通过前面7篇的学习,有点乏味了~~~这篇来学习一个技巧,大家一起想想如果我要在Customer类中实现一个Fullname属性 ...