UVa 12265 - Selling Land
链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3417
题意:
输入一个n*m(1≤n,m≤1000)矩阵,每个格子可能是空地,也可能是沼泽。对于每个空地格子,
求出以它为右下角的空地矩形的最大周长,然后统计每个周长出现了多少次。
分析:
扫描法 + 单调栈。
按照从上到下的顺序处理每一行,在每一行中从左到右处理每个格子(以下称为“当前格”),
找出以该格子为右下角的最大周长矩形(以下简称最优矩形)。只要找到了以每个
格子为右下角的最优矩形,本题就可以得到解决。
假定“当前格”已经固定,则只需要再确定一个左上角,就可以得到一个矩形。
下面用c表示第c列,h表示第c列的空地高度。
首先从上到下枚举“当前行”,然后从左到右枚举“当前列”。
在移动“当前列”的过程中,保存若干个(c,h),按照c从小到大排列成有序表,
则h也是从小到大排列,并且h-c也是从小到大排列。则可以在O(1)时间
内求出每个当前格对应的最优矩形(因为最后一个矩形就是最优的),然后根据需要从右到
左删除一些矩形(也可能不删除),并且可能会把最右边的矩形变矮。然后,当且仅当新矩
形的h-c比它左边的矩形大时,加到表的最右边。由于添加和删除都在表的最右端,用一个
栈来实现即可。
代码:
#include <cstdio>
#include <cstring> const int UP = + ; struct NODE {
int c, h;
} K[UP]; //栈 int hei[UP], ans[UP*];
char s[UP][UP]; int main(){
int T, n, m;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &m);
for(int i = ; i < n; i++) scanf("%s", s[i]); memset(hei, , sizeof(hei));
memset(ans, , sizeof(ans));
for(int r = ; r < n; r++){
int p = ; //栈顶指针
for(int c = ; c < m; c++){
if(s[r][c] == '#') p = hei[c] = ;
else{
hei[c]++;
NODE nd = (NODE){c, hei[c]};
if(!p) K[++p] = nd;
else{
while(p && nd.h <= K[p].h) nd.c = K[p--].c;
if(!p || nd.h - nd.c > K[p].h - K[p].c) K[++p] = nd;
}
ans[K[p].h + c - K[p].c + ]++;
}
}
} for(int i = ; i <= m + n; i++) if(ans[i]){
printf("%d x %d\n", ans[i], i * );
}
}
return ;
}
UVa 12265 - Selling Land的更多相关文章
- UVa 12265 (单调栈) Selling Land
紫书上分析了很多很多,超详细,= ̄ω ̄= 每扫描一行可以计算一个height数组,表示从这块空地向上延伸多少块空地,而且这个数组可以逐行递推. 首先对于每一行来说维护一个单调栈,栈里放的是矩形的左上角 ...
- UVa 12265 贩卖土地 单调栈
题意 输入一个\(n\times m\)的矩阵,每个格子可能是空地,也可能是沼泽.对于每个空地格子,求出以它为右下角的空矩形的最大周长,然后统计每个周长出现了多少次. 思路 对于 每一行 每两个沼泽之 ...
- uva12265 Selling Land
见紫书.(c,h)的更新策略://前面的高度为0了,直接插入因为ans==-c+h,c大,h还小,那么肯定不是最优左上角,更新新加入列的列//新的一列高度最小,就删掉了其他的,只留这个高度从上到下,从 ...
- Uva 4916 Selling Cells(随机算法)
题意: 给定n个圆的 坐标 和半径, 求第一个圆与其他圆相交的面积占第一个圆的面积的多大. 分析: 如果从局部去想, 处理每个圆之间的关系, 求出他们与第一个圆的交集, 这样可能就会十分复杂了. 不妨 ...
- uva 12265 贩卖土地
题目大意: 有一个矩阵 有些点可以取有些不能 求以每个点为右下角的子矩阵(里面点都可以取)的周长最大值 最后统计出每个周长对应矩阵的个数 思路: 单调栈 先预处理出每个点向上最多能延伸多长记为h(i, ...
- 紫书 例题8-19 UVa 12265 (扫描法+单调栈)
首先可以用扫描法处理出一个height数组, 来保存从当前行开始, 每一个格子可以向上延伸的最大长度. 这种"延伸"的问题用扫描法, 因为往往这个时候可以利用前一次的结果来更新当前 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- NOIP2018 - 暑期博客整理
暑假写的一些博客复习一遍.顺便再写一遍或者以现在的角度补充一点东西. 盛暑七月 初涉基环外向树dp&&bzoj1040: [ZJOI2008]骑士 比较经典的基环外向树dp.可以借鉴的 ...
- UVa 10074 - Take the Land
题目大意:和UVa 836 - Largest Submatrix差不多,只需要修改一下数据就可以了. #include <cstdio> #include <cstring> ...
随机推荐
- c++字符前面的L和_T
字符串前面加L表示该字符串是Unicode字符串._T是一个宏,如果项目使用了Unicode字符集(定义了UNICODE宏),则自动在字符串前面加上L,否则字符串不变.因此,Visual C++里边定 ...
- MySQL触发器基本使用
文章参考:这里 MySQL中,创建触发器的基本语法: CREATE TRIGGER trigger_name trigger_time trigger_event ON tbl_name FOR EA ...
- SpringBoot和SpringCloud区别
SpringBoot专注于快速方便的开发单个个体微服务. SpringCloud是关注全局的微服务协调整理治理框架,它将SpringBoot开发的一个个单体微服务整合并管理起来, 为各个服 ...
- Chetsheet: 2017 01.01 ~ 01.31
Web TypeScript: the missing introduction Async HTTP API and service bus Optimizing the Performance o ...
- javaweb之jsp的属性范围
1.什么是jsp的属性范围? 所谓的属性范围就是一个属性设置之后,可以经过多少个其他页面后仍然可以保存并继续使用.jsp提供了四种属性范围,如下: 当前页,对应的jsp对象为pageContext,属 ...
- oracle 基础笔记
sqlplus / as sysbda;-- 运行命令conn scott/tiger [as sysdba];-- 登录show user;查看当前用户alter user scott accoun ...
- C# 索引器的使用
索引器允许类或者结构的实例按照与数组相同的方式进行索引取值,索引器与属性类似,不同的是索引器的访问是带参的. 索引器和数组比较: (1)索引器的索引值(Index)类型不受限制 (2)索引器允许重载 ...
- UFW Essentials: Common Firewall Rules and Commands
Introduction UFW is a firewall configuration tool for iptables that is included with Ubuntu by defau ...
- kafka controller重构
Kafka Controller 是 Kafka 的核心组件,在前面的文章中,已经详细讲述过 Controller 部分的内容.在过去的几年根据大家在生产环境中应用的反馈,Controller 也积累 ...
- 关于安卓开发的学习一:webview
在网上看到几篇不错的博客,分享和学习一下! Android使用WebView加载网页 https://blog.csdn.net/tuke_tuke/article/details/51684254 ...