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. Jquery元素选取、常用方法

    一:常用的选择器:(李昌辉) 基本选择器 $("#myDiv") //匹配唯一的具有此id值的元素 $("div") //匹配指定名称的所有元素 $(" ...

  2. javascript 表单

    在HTML中,表单是由<form>元素来组成的.在js中,表单对应的则是HTMLFormElement类型.它和其他HTML元素一样具有相同的默认属性.下面是HTMLFormElement ...

  3. 时光倒流程序设计-AlloyTicker

    熵与负熵 熵遵循熵增原理,即无序非热能与热能之间的转换具有方向性.薛定谔说过:生命本质在于负熵.熵代表的是无序,负熵就是熵的对立,而负熵表示的则是有序.汲取负熵(米饭.面包.牛奶.鸡蛋),可以简单的理 ...

  4. 如何在SharePoint 当中使用纯JSOM上传任意二进制文件(小于2MB)

    在微软的官方网站上有关于如何在SharePoint当中使用JS创建一个简单的文本文件的例子,经过我的思考我觉得结合Html5特性的浏览器,是完全可以通过JS来读取到文件的内容的(这一部分的内容请大家自 ...

  5. iOS UIApplication sharedapplication用法

    应用中打开其他应用 我们来讨论一下,在iOS开发中,如何实现从app1打开app2. 基本的思路就是,可以为app2定义一个URL,在app1中通过打开这个URL来打开app2,在此过程中,可以传送一 ...

  6. web移动端开发技巧与注意事项汇总

    一.meta的使用 1.<meta name="viewport" content="width=device-width,initial-scale=1.0, m ...

  7. hive 调优总结

    一.join优化 做join之前对数据进行预处理,减少参加join的数据量,把数据量少的表放入内存中,制作map端的join 应该将条目少的表/子查询放在 Join 操作符的左边.原因是在 Join  ...

  8. T-SQL 转义select … like中的特殊字符(百分号)

    众所周知,T-SQL中LIKE运算符使用%符号表示通配符.很多时候可能需要查询包含有%的数据,比如需要查询字段coupon中含有5%的数据.那么如何使用已经有百分号(%)符号的LIKE搜索字符串呢? ...

  9. ASP.NET Cookie(一)--基本应用

    Cookie提供了一种在Web应用程序中存储用户特定信息的方法.例如,当用户访问您的站点时,您可以使用Cookie存储用户首选项或其他信息.当该用户再次访问您的网站时,应用程序便可以检索以前存储的信息 ...

  10. MVC中部分视图调用方法总结

    部分视图不走  controller @Html.Partial(“_Menu”);  //这种是不走Controller的,直接在加载_Menu的视图 @Html.Partial(“_Menu”, ...