1127: [POI2008]KUP

Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special Judge
Submit: 317  Solved: 111
[Submit][Status][Discuss]

Description

给一个n*n的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于[k,2k]

Input

输入k n(n<2000)和一个n*n的地图

Output

输出矩形的左上和右下的列-行坐标或NIE

Sample Input

inputdata1
4 3
1 1 1
1 9 1
1 1 1
inputdata2
8 4
1 2 1 3
25 1 2 1
4 20 3 3
3 30 12 2

Sample Output

outputdata1
NIE
outputdata2
2 1 4 2

HINT

1<=k<=10^9 每个价格都是不大于2*10^9的非负整数

Source

感谢vfleaking提供SPJ

Solution

这个题需要思路....

首先假设有一个一维的区间$[l,r]$,那么假设这个区间中满足$\forall x,x<K$,那么且这个区间的和$>=K$,那么答案肯定存在在这个区间中。

证明:

因为这个区间中满足$\forall x,x<K$,所以区间和每加上一个数,区间和的变化量一定是$<K$的;

所以,并不会存在一个数使得一个子区间(连续的)和加上他得到的新区间和直接从$(-\infty,K]$跳过$[K,2*K]$变成$[2*K,+\infty)$.

所以,只要从这个一维的区间的左/右端开始一一删除,就可以得到满足条件的区间。

但是这里的$N*N$的矩阵,所以要利用这个结论就必须扩展到多维区间块上面,但是这个结论是可以拓展的。

这样就是一个子矩阵满足$\forall x,x<K$,且子矩阵和$>=K$,那么这个子矩阵中存在答案。

证明类比上面的证明,这里分类讨论一下,可以利用上面的方法,先一行一行的删除,删成满足条件的,或者只剩一行,转成上述,再一个一个删.

然后就是找出这些需要搞得子矩形的方法了,把$x>2*K$的点认为是障碍,做一遍悬线法,就可以得到所有的极大子矩形,然后一一判断。

当然一开始读入的时候,如果存在一个$1*1$的位置$x$直接满足$x \in [K,2*K]$那么可以直接输出。

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define LL long long
inline int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
int K,N,l[][],r[][],h[][];
LL sum[][],a[][];
inline LL Sum(int x1,int y1,int x2,int y2) {return sum[x2][y2]+sum[x1-][y1-]-sum[x2][y1-]-sum[x1-][y2];}
inline void Cut(int x1,int y1,int x2,int y2)
{
while (Sum(x1,y1,x2,y2)>*K)
{
if (x1==x2) {y2--; continue;}
if (Sum(x1,y1,x2-,y2)>=K) {x2--; continue;}
if (Sum(x1+,y1,x2,y2)>=K) {x1++; continue;}
}
printf("%d %d %d %d\n",y1,x1,y2,x2);
exit();
}
int main()
{
K=read(),N=read();
for (int i=; i<=N; i++)
for (int j=; j<=N; j++)
a[i][j]=read(),sum[i][j]=sum[i-][j]+sum[i][j-]-sum[i-][j-]+a[i][j];
for (int i=; i<=N; i++)
for (int j=; j<=N; j++)
if (a[i][j]>=K && a[i][j]<=*K) {printf("%d %d %d %d\n",j,i,j,i); return ;}
for (int i=; i<=N; i++)
{
for (int j=,x=; j<=N; j++)
if (a[i][j]<=*K) l[i][j]=x; else l[i][j]=,x=j;
for (int j=N,x=N+; j>=; j--)
if (a[i][j]<=*K) r[i][j]=x; else r[i][j]=N+,x=j;
}
for (int i=; i<=N+; i++) r[][i]=N+;
for (int i=; i<=N; i++)
for (int j=; j<=N; j++)
if (a[i][j]<=*K)
h[i][j]=h[i-][j]+,
l[i][j]=max(l[i][j]+,l[i-][j]),
r[i][j]=min(r[i][j]-,r[i-][j]); // puts("==========================");
// for (int i=1; i<=N; i++,puts(""))
// for (int j=1; j<=N; j++)
// printf("%d ",h[i][j]);
// puts("==========================");
// for (int i=1; i<=N; i++,puts(""))
// for (int j=1; j<=N; j++)
// printf("%d ",l[i][j]);
// puts("==========================");
// for (int i=1; i<=N; i++,puts(""))
// for (int j=1; j<=N; j++)
// printf("%d ",r[i][j]);
// puts("=========================="); for (int i=; i<=N; i++)
for (int j=; j<=N; j++)
if (a[i][j]<=*K){
// printf("%d %d %d %d\n",i-h[i][j]+1,l[i][j],i,r[i][j]);
if (Sum(i-h[i][j]+,l[i][j],i,r[i][j])>=K) Cut(i-h[i][j]+,l[i][j],i,r[i][j]);
}
puts("NIE");
return ;
}
/*
2 3
3 25 7
6 1 2
16 11 20
*/

【BZOJ-1127】KUP 悬线法 + 贪心的更多相关文章

  1. bzoj1127[POI2008]KUP 悬线法

    Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 485  Solved: 174[Submit][Status][D ...

  2. BZOJ 1057: [ZJOI2007]棋盘制作( dp + 悬线法 )

    对于第一问, 简单的dp. f(i, j)表示以(i, j)为左上角的最大正方形, f(i, j) = min( f(i + 1, j), f(i, j + 1), f(i + 1, j + 1)) ...

  3. BZOJ 3039: 玉蟾宫( 悬线法 )

    最大子矩阵...悬线法..时间复杂度O(nm) 悬线法就是记录一个H向上延伸的最大长度(悬线), L, R向左向右延伸的最大长度, 然后通过递推来得到. ----------------------- ...

  4. 悬线法 || BZOJ 1057: [ZJOI2007]棋盘制作 || Luogu P1169 [ZJOI2007]棋盘制作

    题面:P1169 [ZJOI2007]棋盘制作 题解: 基本是悬线法板子,只是建图判断时有一点点不同. 代码: #include<cstdio> #include<cstring&g ...

  5. 【BZOJ】1057 [ZJOI2007]棋盘制作(悬线法)

    题目 传送门:QWQ 分析 先把题目给出的矩阵变换一下,如果$ a[i][j] $中$ i+j \mod 2 = 1 $那么就对$ a[i][j] $取一下反. 接着就是求原图中最大的0.1子矩阵 详 ...

  6. 【BZOJ】3039: 玉蟾宫 悬线法

    [题意]给定01矩阵,求最大全1子矩阵.n,m<=1000. [算法]动态规划(悬线法) [题解]★对于01矩阵中的任意一个全1极大子矩阵,都可以在其上边界遇到的障碍点处悬线到下边界的点x,则点 ...

  7. BZOJ 1057: [ZJOI2007]棋盘制作 悬线法求最大子矩阵+dp

    1057: [ZJOI2007]棋盘制作 Description 国际象棋是世界上最古老的博弈游戏之一,和中国的围棋.象棋以及日本的将棋同享盛名.据说国际象棋起源于易经的思想,棋盘是一个8*8大小的黑 ...

  8. bzoj 1127 KUP —— 最大子矩形+答案构造

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1127 首先,把权值 > 2*k 的点作为“坏点”,然后在图中用悬线法找权值最大的子矩形 ...

  9. 【BZOJ-3039&1057】玉蟾宫&棋盘制作 悬线法

    3039: 玉蟾宫 Time Limit: 2 Sec  Memory Limit: 128 MBSubmit: 753  Solved: 444[Submit][Status][Discuss] D ...

随机推荐

  1. struts2中从后台读取数据到<s:select>

    看到网上好多有struts2中从后台读取数据到<s:select>的,但都 不太详细,可能是我自己理解不了吧!所以我自己做了 一个,其中可能 有很多不好的地方,望广大网友指出 结果如图 p ...

  2. 重新诠释的OSGi规范

    上周五部门开会讨论新一代产品(基于.net Winform)的设计规范,从设计规范慢慢讨论到体系结构等架构存在的问题,诸如菜单.工具条.状态条.界面布局等不能实现配置化和自动化,子系统之间拥有强依赖, ...

  3. ERDAS 2014安装破解及汉化图文教程

    关于ERDAS 2014 的安装破解及其汉化过程: 说明:汉化只是之针对英语能力不能正常满足使用软件的朋友们.如果英语过专八,完全没有必要汉化!在此之前查了好多关于ERDAS汉化的文档,可惜只是简单的 ...

  4. 菜鸟快飞之JavaScript对象、原型、继承(三)

    正文之前需要声明的一点是,菜鸟系列博文全是基于ES5的,不考虑ES6甚至更高版本. 继承 由于我个人不是学计算机的,所以对于很多东西只是知其然,不知其所以然.就像这个继承,刚开始学JavaScript ...

  5. iOS开发中常用的设计模式

    常用的设计模式(一)代理模式应用场景:当一个类的某些功能需要由别的类来实现,但是又不确定具体会是哪个类实现.优势:解耦合敏捷原则:开放-封闭原则实例:tableview的 数据源delegate,通过 ...

  6. 在Ubuntu和Linux Mint上安装Oracle JDK

    在Ubuntu和Linux Mint上安装Oracle JDK 使用下面的命令安装,只需一些时间,它就会下载许多的文件,所及你要确保你的网络环境良好: sudo add-apt-repository ...

  7. 玩转Podfile

    前言 经常使用CocoaPods来管理iOS项目中的第三方库,但是我们要使用CocoaPods来管理第三方库,前提是要写好Podfile文件,通过这个文件来配置第三方库与项目之间的依赖.版本等信息. ...

  8. 原创 C++应用程序在Windows下的编译、链接(四)动态链接

    4动态链接 4.1概述 在静态链接阶段,链接器为PE文件生成了导入表,导出表,符号表,并调整了Call指令后面的操作数,在程序调用的时候,能够直接地或者间接地定位到IAT中的某个位置,在PE文件中,该 ...

  9. SQL Server封闭掉 触发器递归

    SQL Server关闭掉 触发器递归SQL Server  是有一个开关, 可以关闭掉 触发器递归的.EXEC sp_dboption '数据库名字', 'recursive triggers', ...

  10. 在Ubuntu中建立MySQL数据库

    最近在做一个关于云计算安全系统的项目,需要用到MySQL数据库,现在把建立数据库的步骤记录下来. 一.用命令在Ubuntu上安装MySQL # sudo apt-get update # sudo a ...