题目

https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=1030

题意

矩阵,有障碍和普通地面两种子元素,求普通地面连成的子矩阵面积最大值 * 3

思路

如刘书

对于子矩阵长方形来说,其底边上必然有一点,该点向上可以延伸的距离就是子矩阵的长,枚举这一点,设为(i,j)。(i,j)不是障碍是普通地面。

令up[i][j]为其向上能延伸的距离,llen[i][j]为以up[i][j]为长的长方形,左边最早开始于哪里,rlen[i][j]为依此右边最晚结束于哪里。

up[i][j]=(i?up[i - 1][j] + 1)

但要如何更新llen和rlen呢?

考虑上方(i - 1, j),如果(i - 1, j)是障碍,那么up[i][j] = 1, llen[i][j]就是(i, j)左边的障碍横坐标+1,rlen以此类推。

如果(i- 1, j)不是障碍,第一种情况,llen[i][j] = llen[i - 1][j],在这多填出的一层内没有障碍物,另一种情况,llen[i][j]依然是(i, j)左边的障碍横坐标+1。

rlen以此类推。

感想

1. 一开始没有想到枚举(i,j)这根作为面积的长,而只是想到枚举(i,j)作为右下角。这样就还要用费时间的方式确定此时的面积长。

2. 后来没想到可以用上方而不是左方来更新rlen或者llen。没有意识到如果上方是障碍,那么只要看左/右的障碍在哪里即可。

3. 最后本来用的是(i && maze[i - 1][j] != 'R'),不知道哪里错了

代码

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <tuple>
#define LOCAL_DEBUG
using namespace std;
const int MAXN = 1e3 + ;
char maze[MAXN][MAXN];
int up[MAXN][MAXN];
int llen[MAXN][MAXN];
int rlen[MAXN][MAXN]; int main() {
#ifdef LOCAL_DEBUG
freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\input.txt", "r", stdin);
//freopen("C:\\Users\\Iris\\source\\repos\\ACM\\ACM\\output.txt", "w", stdout);
#endif // LOCAL_DEBUG
int T;
scanf("%d", &T);
for (int ti = ; ti <= T; ti++) {
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i < n; i++) {
for (int j = ; j < m; j++) {
char tmp[];
scanf("%s", tmp);
maze[i][j] = tmp[];
}
} for (int i = ; i < n; i++) {
for (int j = , last_impede=-; j < m; j++) {
if (maze[i][j] == 'R') {
up[i][j] = ;
llen[i][j] = ;
last_impede = j;
}
else {
up[i][j] = (i ? up[i - ][j] : ) + ;
llen[i][j] = max((i ? llen[i - ][j] : ), last_impede + );
}
}
}
int ans = ;
for (int i = ; i < n; i++) {
for (int j = m - , last_impede = m; j >= ; j--) {
if (maze[i][j] == 'R') {
rlen[i][j] = m;
last_impede = j;
}
else {
rlen[i][j] = min((i ? rlen[i - ][j] : m), last_impede - );
ans = max(ans, up[i][j] * (rlen[i][j] - llen[i][j] + ));
}
}
}
printf("%d\n", ans * );
} return ;
}

UVa LA 3029 City Game 状态拆分,最大子矩阵O(n2) 难度:2的更多相关文章

  1. LA 3029 City Game

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

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

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

  3. UVA LA 7146 2014上海亚洲赛(贪心)

    option=com_onlinejudge&Itemid=8&page=show_problem&category=648&problem=5158&mosm ...

  4. LA 3029 Subsequence

    LA 3029 A sequence of N positive integers (10 < N < 100 000), each of them less than or equal ...

  5. UVa LA 3695 - Distant Galaxy 前缀和,状态拆分,动态规划 难度: 2

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

  6. UVa LA 2965 - Jurassic Remains 中间相遇,状态简化 难度: 2

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

  7. Uva LA 3177 - Beijing Guards 贪心,特例分析,判断器+二分,记录区间内状态数目来染色 难度: 3

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

  8. .Uva&LA部分题目代码

    1.LA 5694 Adding New Machine 关键词:数据结构,线段树,扫描线(FIFO) #include <algorithm> #include <cstdio&g ...

  9. uva 11195 Another queen (用状态压缩解决N后问题)

    题目链接:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem& ...

随机推荐

  1. QT绘制饼图

    QT版本:QT5.6.1 QT绘制饼图,出问题的代码如下 void DrawPieDialog::paintEvent(QPaintEvent *event) { float startAngle=0 ...

  2. Qt5获取本机网络信息

    获取本机网络信息 在pro文件中加入如下代码 QT += network widget.h中的代码如下 #ifndef WIDGET_H #define WIDGET_H #include <Q ...

  3. 主元素问题 Majority Element

    2018-09-23 13:25:40 主元素问题是一个非常经典的问题,一般来说,主元素问题指的是数组中元素个数大于一半的数字,显然这个问题可以通过遍历计数解决,时间复杂度为O(n),空间复杂度为O( ...

  4. HeadFirst Ruby 第七章总结 references

    前言 这一章的内容关于 references,讲了当 Ruby 程序中可能会遇到关于 reference 与 object 之间概念混淆而导致的问题. 导言 本章从一个 astronomer 发现 s ...

  5. 11月24日 layouts and rendering in rails(部分没有看)

    http://guides.rubyonrails.org/layouts_and_rendering.html  中文 This guide covers the basic layout feat ...

  6. android--------Socket的简单了解

    Socket目录 Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连 ...

  7. [LintCode] Number of Islands(岛屿个数)

    描述 给一个01矩阵,求不同的岛屿的个数. 0代表海,1代表岛,如果两个1相邻,那么这两个1属于同一个岛.我们只考虑上下左右为相邻. 样例 在矩阵: [ [1, 1, 0, 0, 0], [0, 1, ...

  8. 2-SET 前缀优化建图

    1, Duff in Mafia CodeForces - 587D 2, Ants CodeForces - 1007D

  9. python-day71--django多表双下划线查询及分组聚合及F/Q查询

    #====================================双下划线的跨表查询===============# 前提 此时 related_name=bookList 属性查询: # 查 ...

  10. leetcode-algorithms-26 Remove Duplicates from Sorted Array

    leetcode-algorithms-26 Remove Duplicates from Sorted Array Given a sorted array nums, remove the dup ...