Vijos-P1057题解
本文为原创,转载请注明:http://www.cnblogs.com/kylewilson/
题目出处:
题目描述:
给一个N*M的土地,由0和1表示,0表示瑕疵,1表示完好,找出最大的完好的正方形土地?
输入:
输入文件第一行为两个整数n,m(1<=n,m<=1000),接下来n行,每行m个数字,用空格隔开。0表示该块土地有瑕疵,1表示该块土地完好
4 4
0 1 1 1
1 1 1 0
0 1 1 0
1 1 0 1
思路分析:
首先看数据范围,1~1000,存储地图需要O(n*m)的内存空间,空间复杂度可控;再看时间复杂度,遍历所有点为O(n*m);
为什么要先分析空间及时间复杂度呢?因为很多时候,数据规模就决定了算法,如果数据规模为1~1000000000,你还会考虑O(n*n)的算法吗,肯定不会,这种数据一看就知道最优解法为线性复杂度O(n)的算法;
列举如下3处情况:图中彩色方框都为1,白色方框都为0

假设地图中存在一个最大的正方形,则该正方形存在一个右下角P点,且该点为1;
如果当某一个点P(i,j)为0时,则以该点为右下角不存在正方形,所以该点也不可能在最大的正方形中。
不同情况列举:
图P1.1
当P(i,j)=1时,可以看出以P为右下角,最优解由红色边长决定,即以P点为起点,向左连续为1的最多个数,木桶原理
图P1.2
当P(i,j)=1时,可以看出以P为右下角,最优解由紫色边长决定,即以M点为右下角能组成的最大的正方形
图P1.3
当P(i,j)=1时,可以看出以P为右下角,最优解由绿色边长决定,即以P点为起点,向上连续为1的最多个数
则可以建立如下DP公式
设f[i][j]:以点(i,j)为右下角,能组成的最大正方形边长
left[i][j]:以点(i,j)为起点,向左最大连续1的个数,提前初始化
up[i][j]:以点(i,j)为起点,向上最大连续1的个数,提前初始化
f[i][j]=max(f[i-1][j-1]+1, left[i][j], up[i][j])
注:地图为一行或者一列时,提前预处理,方便后面递推
C++源码如下:
github: https://github.com/Kyle-Wilson1/Vijos/tree/master/P1057
#include <iostream>
#include <fstream>
#include <vector> using namespace std; struct Node {
int left, up;
}; int main() {
ifstream cin("a.in");
ofstream cout("a.out"); vector<vector<int>> f(1000, vector<int>(1000, 0));
vector<vector<int>> map(1000, vector<int>(1000, 0));
Node initNode{0, 0};
vector<vector<Node>> node(1000, vector<Node>(1000, initNode)); int n, m, i, j, maxSquare = 0; cin >> n >> m;
//input
for (i = 0; i < n; i++)
for (j = 0; j < m; j++)
cin >> map[i][j]; //init left
for (i = 0; i < n; i++)
for (j = 0; j < m; j++) {
if (j == 0) {
if (map[i][j] == 1) {
node[i][j].left = 1;
} else { node[i][j].left = 0; }
} else {
if (map[i][j] == 1) {
node[i][j].left = node[i][j - 1].left + 1;
} else {
node[i][j].left = 0;
}
}
} //init up
for (j = 0; j < m; j++)
for (i = 0; i < n; i++) {
if (i == 0) {
if (map[i][j] == 1) {
node[i][j].up = 1;
} else { node[i][j].up = 0; }
} else {
if (map[i][j] == 1) {
node[i][j].up = node[i - 1][j].up + 1;
} else {
node[i][j].up = 0;
}
}
} auto maxOfTwo = [](int a, int b) { return a > b ? a : b; };
auto minOfThree = [](int a, int b, int c) { return a < b ? a < c ? a : c : b < c ? b : c; }; //dynamic programming
for (i = 0; i < n; i++) {
if (map[i][0] == 1) {
f[i][0] = 1;
maxSquare = 1;
} else f[i][0] = 0;
} for (j = 1; j < m; j++) {
if (map[0][j] == 1) {
f[0][j] = 1;
maxSquare = 1;
} else f[0][j] = 0;
} for (i = 1; i < n; i++)
for (j = 1; j < m; j++) {
f[i][j] = minOfThree(node[i][j].left, node[i][j].up, f[i - 1][j - 1] + 1);
maxSquare = maxOfTwo(f[i][j], maxSquare);
} cout << maxSquare;
cin.close();
cout.close();
return 0;
}
Vijos-P1057题解的更多相关文章
- 区间 (vijos 1439) 题解
[问题描述] 现给定n个闭区间[ai,bi],1<=i<=n.这些区间的并可以表示为一些不相交的闭区间的并.你的任务就是在这些表示方式中找出包含最少区间的方案.你的输出应该按照区间的升序排 ...
- vijos题解
Vijos题解 题库地址:https://vijos.org/p P1001 谁拿了最多奖学金 题意:按照指定要求计算奖学金,直接用if判断即可 #include<iostream> us ...
- [题解]vijos & codevs 能量项链
a { text-decoration: none; font-family: "comic sans ms" } .math { color: gray; font-family ...
- [题解]vijos 运输计划
Description 公元 2044 年,人类进入了宇宙纪元.L 国有 n 个星球,还有 n−1 条双向航道,每条航道建立在两个星球之间,这 n−1 条航道连通了 L 国的所有星球.小 P 掌管一家 ...
- 集合删数 (vijos 1545) 题解
[问题描述] 一个集合有如下元素:1是集合元素:若P是集合的元素,则2 * P +1,4*P+5也是集合的元素,取出此集合中最小的K个元素,按从小到大的顺序组合成一个多位数,现要求从中删除M个数位上的 ...
- 洛谷P1057传球游戏题解
题目 这个题表面上看并不像DP,但是当我们看到方案数时,我们可能会想到什么??? 对,分类加法原理,在每一轮中,每一个点的方案数都要加上这个点左边的方案与右边的方案. 因此我们可以枚举,设一个DP数组 ...
- 小胖守皇宫(VIJOS P1144 )题解
题目描述 huyichen世子事件后,xuzhenyi成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:某些宫殿间可以互相望见.大内保卫森严,三步一岗,五步一哨,每 ...
- vijos P1915 解方程 加强版
背景 B酱为NOIP 2014出了一道有趣的题目, 可是在NOIP现场, B酱发现数据规模给错了, 他很伤心, 哭得很可怜..... 为了安慰可怜的B酱, vijos刻意挂出来了真实的题目! 描述 已 ...
- 【BZOJ 1065】【Vijos 1826】【NOI 2008】奥运物流
http://www.lydsy.com/JudgeOnline/problem.php?id=1065 https://vijos.org/p/1826 好难的题啊TWT ∈我这辈子也想不出来系列~ ...
- Vijos1448校门外的树 题解
Vijos1448校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...
随机推荐
- 【python】入门:打印字符串、简单计算
- JavaScript基础2——关于变量
变量的声明 变量的定义:使用var关键字来声明,区分大小写的.注意:不用var,会污染全局变量. 变量的命名规范是:字母,数字,$符 ...
- iOS 页面之间的专长动画控制器间的转换
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; line-height: 24.0px; font: 14.0px "Heiti SC Light" ...
- Java I/O---RandomAccessFile类(随机访问文件的读取和写入)
1.JDK API中RandomAccessFile类的描述 此类的实例支持对随机访问文件的读取和写入.随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组.存在指向该隐含数组的光标或索引 ...
- iOS通用链接(Universal Links)突然点击无效的解决方案
接上文<微信中通过页面(H5)直接打开本地app的解决方案>已经把iOS搞定并且已经正常能跑了,突然就再也用不了了... 问题描述 测试告诉我,如果从微信打开App之后,点击App右上角的 ...
- dropout理解:1神带9坑
Dropout是深度学习中防止过拟合的一项非常常见的技术,是hinton大神在12年提出的一篇论文里所采用的方法.有传言hinton大神的数学功底不是很好,所以他所提出的想法背后的数学原理并不是很复杂 ...
- 根据NPOI 读取一个excel 文件的多个Sheet
大家都知道NPOI组件可以再你本地没有安装office的情况下来 读取,创建excel文件.但是大家一般都是只默认读取一个excel文件的第一个sheet.那么如果要读取一个excel 的所有shee ...
- Xamarin~Android篇~监听返回键,单击返回某个webView,双击退出
https://www.cnblogs.com/lori/p/5088627.html DateTime? lastBackKeyDownTime; public override bool OnKe ...
- [APIO2010]特别行动队
题目描述 你有一支由 n 名预备役士兵组成的部队,士兵从 1 到 n 编号,要将他们拆分 成若干特别行动队调入战场.出于默契的考虑,同一支特别行动队中队员的编号 应该连续,即为形如(i, i + 1, ...
- 房上的猫:switch选择结构,与选择结构总结
switch选择结构: 一.定义: switch选择结构,可以方便地解决等值判断问题二.语法: switch(表达式){ case 常量1: //代码块1; break; c ...