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. ASP.NET CORE配置信息

    做个笔记,原文链接 除了应用 IOptions<T> .Value的方式对配置信息进行全局注册外可以应用的另一个微软给出的组件,需要依赖两个包 Microsoft.Extensions.C ...

  2. CSS3 Flexbox轻松实现元素的水平居中和垂直居中

    CSS3 Flexbox轻松实现元素的水平居中和垂直居中 网上有很多关于Flex的教程,对于Flex的叫法也不一,有的叫Flexbox,有的叫Flex,其实这两种叫法都没有错,只是Flexbox旧一点 ...

  3. 初试WIX加SQL LocalDB

    最近有个项目需要生成一个自动打包安装App和数据库的MSI文件,经同事推荐WIX,于是乎就试了一试.遇到了一些问题觉得有分享的价值,所以写篇博客记录一下 :) 使用感觉: WIX特点:功能很强大,用X ...

  4. 【MSSQL】MSSQL还原单mdf文件报1813错误

    序: MS SQL Server 2008 r2附加无ldf日志的mdf数据库时报1813错误.提示数据库被强制分离,无日志不能还原之类的话. 可能的原因: 原因系统正在执行定时作业,没有主要到多次强 ...

  5. Linux 查看命令源码

    一.简介 有时候想看看ls.cat.more等命令的源代码,本文介绍相应查看方法. 二.方法 参考: http://blog.csdn.net/silentpebble/article/details ...

  6. 如果layer层在iframe下不居中滚动

    需要在layer前面加上parent.layer. 2.运用layer层的步骤: 1.引入1.8版本以上的jquery文件 <script type="text/javascript& ...

  7. Ubuntu15.10下华南师大锐捷认证客户端的使用详解

    本文测试Linux系统环境为Ubuntu15.10 Destop,暂未在其他系统下验证过,不代表LTS版本或较旧的版本按照本文所述方法可以100%正确使用最新的锐捷认证客户端. 本文面向对象为华南师范 ...

  8. WinForm TreeView递归加载

    这个其实通俗一点讲就是的树状分支图 首先利用递归添加数据 数据放入 treeView1.Nodes.Add() 中 public Form3() { InitializeComponent(); Tr ...

  9. Spring 框架的架包分析、功能作用、优点,及jar架包简介

    Spring 框架的架包详解    Spring的作用     Spring的优势  由于刚搭建完一个MVC框架,决定分享一下我搭建过程中学习到的一些东西.我觉得不管你是个初级程序员还是高级程序员抑或 ...

  10. python sokct 包详解

    1. getaddrinfo简介getaddrinfo可解析得到IPv6地址,而gethostbyname仅能得到IPv4地址.getaddrinfo在Python的socket包中,以下为pytho ...