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校门外的树 题解 描述: 校门外有很多树,有苹果树,香蕉树,有会扔石头的,有可以吃掉补充体力的…… 如今学校决定在某个时刻在某一段种上一种树,保证任一时刻不会出现两段相同种类的树,现 ...
随机推荐
- redis的list类型
1.简单介绍 redis的list类型其实就是一个每个元素都是string类型的双向链表.所以lpush.rpush.lpop和rpop命令的时间复杂度是O(1),list会记录链表的长度,所以lle ...
- gunicorn geventworker 解析
在前面的文章曾介绍过gunicorn的syncworker,本文介绍其中一种asyncworker:GeventWorker.类图如下: 可见GeventWorker重载了init_process ...
- java 单例模式学习笔记
1.单例模式概述 单例模式就是确保类在内存中只有一个对象,该实例必须自动创建,并且对外提供. 2.优缺点 优点:在系统内存中只存在一个对象,因此可以节约系统资源,对于一些需要频繁创建和销毁的对象单例模 ...
- eclipse中JPA插件的安装与使用
说明 上周实验室学习了数据库设计相关的内容,其中涉及到将数据库实体化的问题,JPA是一个很好的实现工具,便开始着手于JPA的学习.因为JPA涉及到的知识还是挺多的,需要学习许多新的知识,所以对于JPA ...
- python作用域与命名空间
什么是命名空间 比如有一个学校,有10个班级,在7班和8班中都有一个叫“小王”的同学,如果在学校的广播中呼叫“小王”时,7班和8班中的这2个人就纳闷了,你是喊谁呢!!!如果是“7班的小王”的话,那么就 ...
- 【java】多线程同步生产者消费者问题
package 多线程; class Producer implements Runnable{ private Data data; public Producer(Data data){ this ...
- linux下增加磁盘改变指定文件路径分区挂载点和迁移数据
Centos7 系统上原有目录/data 挂载根目录下,空间有点小,我们需要把/data目录挂载到另一个磁盘,同时把数据迁移. 1.查看分区情况 fdisk -l 2.查看路径对应分区情况 df -l ...
- 【ASP.NET系列】详解Views
描述 本片文章内容属于ASP.NET MVC系列视图篇,主要讲解View,大致内容如下: 1.Views文件夹讲解 2.View种类 3.Razor语法 4.对视图的基本操作 一 Views文件夹 ...
- 关于MAX()函数的一点思考
本文同时发表在https://github.com/zhangyachen/zhangyachen.github.io/issues/103 考虑如下表和sql: CREATE TABLE `ikno ...
- 程序员的自我救赎---11.4:FileSystem文件服务
<前言> (一) Winner2.0 框架基础分析 (二)PLSQL报表系统 (三)SSO单点登录 (四) 短信中心与消息中心 (五)钱包系统 (六)GPU支付中心 (七)权限系统 (八) ...