题解 【POI2008】KUP-Plot purchase
题面
先把题目意思讲一下吧:
给一个 \(n*n\) 的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于\([k,2k]\).
那么首先,可以想到,如果\(a[i][j]\)(格子的价格,下同)位于\([k,2k]\),直接输出就好.
而对于\(a[i][j]\)>\(2k\)的格子,它是不可能被选的,那么可以把它视为障碍物,
然后,剩下的格子的价格就一定小于\(k\).
那么,根据悬线法,
如果我们找到了一个极大子矩阵,且矩阵和(设为\(sum\))>=\(k\)(小于肯定是不行的),
如果\(sum\)<=\(2k\),就直接输出答案,
否则,判断第一行的和\(sum_{1}\),
若\(sum_{1}\)>=\(k\),那在第一行中肯定有解,
因为每个元素都小于\(k\)(前面说过了),
那么不存在一个格子能使矩阵和从大于\(2k\)一下变到小于\(k\),
因此只需要一个个删掉第一行的元素,直到符合要求即可.
而当\(sum_{1}\)<\(k\)时,
因为\(sum\)>\(2k\),
所以可以删掉第一行,再继续判断剩下的矩阵.
这一部分的实现方式:
inline void print_t(int x1,int y1,int x2,int y2)/*以(x1,y1)为左上角,(x2,y2)为右下角*/{
while(sum(x1,y1,x2,y2)/*矩阵和*/>m*2){
if(x1==x2) y2--;
else if(sum(x1,y1,x1,y2)>=m) x2=x1;
else x1++;
}
printf("%d %d %d %d\n",y1,x1,y2,x2);
exit(0);//终止程序
}
最后注意:找到答案后直接终止程序!
上完整代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
int sum=0,f=1;char ch=getchar();
while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0' && ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return f*sum;
}
int n,m;
ll a[2001][2001];//价格
ll s[2001][2001];//二维前缀和
int h[2001][2001]/*悬线*/,l[2001][2001]/*向左展开的位置*/,r[2001][2001]/*向右展开的位置*/;
inline ll sum(int x1,int y1,int x2,int y2)/*矩阵和*/{
return s[x2][y2]+s[x1-1][y1-1]-s[x1-1][y2]-s[x2][y1-1];
}
inline void print_t(int x1,int y1,int x2,int y2){
while(sum(x1,y1,x2,y2)>m*2){
if(x1==x2) y2--;
else if(sum(x1,y1,x1,y2)>=m) x2=x1;
else x1++;
}
printf("%d %d %d %d\n",y1,x1,y2,x2);
exit(0);
}
int main(){
// freopen("kup.in","r",stdin);
// freopen("kup.out","w",stdout);
m=read();n=read();//m就是k,只是看上去顺眼一些而已[滑稽]
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++){
a[i][j]=read();
s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+a[i][j];
if(a[i][j]<m||a[i][j]>2*m) continue;
printf("%d %d %d %d\n",j,i,j,i);
return 0;
}
for(int i=1;i<=n;i++) r[0][i]=n+1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++) h[i][j]= a[i][j]>2*m? 0:h[i-1][j]+1;
for(int i=1;i<=n;i++){
int ret=0;
for(int j=1;j<=n;j++){
if(h[i][j]) l[i][j]=max(l[i-1][j],ret);
else ret=j,l[i][j]=0;
}
ret=n+1;
for(int j=n;j;j--){
if(h[i][j]) r[i][j]=min(r[i-1][j],ret);
else ret=j,r[i][j]=n+1;
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(!h[i][j]) continue;
int x1=i-h[i][j]+1;
int y1=l[i][j]+1,y2=r[i][j]-1;
if(sum(x1,y1,i,y2)<m) continue;
print_t(x1,y1,i,y2);
}
}
puts("NIE");
return 0;
}
题解 【POI2008】KUP-Plot purchase的更多相关文章
- 1127: [POI2008]KUP
1127: [POI2008]KUP https://lydsy.com/JudgeOnline/problem.php?id=1127 分析: 如果存在一个点大于等于k,小于等于2k的话,直接输出. ...
- [BZOJ1127][POI2008] KUP子矩阵
Description 给一个n*n的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于[k,2k] Input 输入k n(n<2000)和一个n*n的地图 Output 输出矩形的左 ...
- bzoj1127: [POI2008]KUP
Description 给一个n*n的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于[k,2k] Input 输入k n(n<2000)和一个n*n的地图 Output 输出矩形的左 ...
- bzoj1127[POI2008]KUP 悬线法
Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 485 Solved: 174[Submit][Status][D ...
- 解题:POI 2008 Plot purchase
题面 原来看过然后没做,结果板板把这道题改了改考掉了,血亏=.= 首先看看有没有符合条件的点.如果没有开始寻找解,先把所有的大于$2*k$的点设为坏点,然后求最大子矩形,只要一个最大子矩形的权值和超过 ...
- [BZOJ] 1127: [POI2008]KUP
似曾相识的感觉 考虑另一个判断问题,给定一个k,问这个k是否可行 存在矩形和\(sum>2k\),则该矩阵不对判定做出贡献 存在矩形和\(sum\in [k,2k]\),则我们找到了一个解 于是 ...
- bzoj 1127 [POI2008]KUP——思路(悬线法)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1127 大于2*K的视为不能选的“坏点”.有单个格子满足的就直接输出. 剩下的都是<K的 ...
- [POI2008]KUP
Description 给一个\(n\times n\)的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于[k,2k] Input 输入k n(n<2000)和一个\(n\times ...
- 【BZOJ-1127】KUP 悬线法 + 贪心
1127: [POI2008]KUP Time Limit: 10 Sec Memory Limit: 162 MBSec Special JudgeSubmit: 317 Solved: 11 ...
随机推荐
- python元组数据类型讲解
元组可以被看成是不能改变的列表.列表是动态的,你可以增添,插入,删除,更改列表元素.有时我们需要这样的操作,但是有些时候我们需要保证有些数据是不能被用户或程序更改的.这就是元组的作用. 准确的说,列表 ...
- python的文件读写操作
文件读写 本文转自廖雪峰老师的教程https://www.liaoxuefeng.com/wiki/1016959663602400/1017607179232640 读写文件是最常见的IO操作.Py ...
- Docker入门(一):安装
一. 安装docker 1. 删除已安装的docker yum remove docker \ docker-client \ docker-client-latest \ docker-common ...
- Java源码 HashMap<K,V>
HashMap类 https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html public class HashMap<K, ...
- JavaScript设计模式(发布订阅模式)
发布—订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都将得到通知.在JavaScript开发中,我们一般用事件模型来替代传统的发布—订阅模式 ...
- 进阶Java编程(1)多线程编程
Java多线程编程 1,进程与线程 在Java语言里面最大的特点是支持多线程的开发(也是为数不多支持多线程的编程语言Golang.Clojure方言.Elixir),所以在整个的Java技术学习里面, ...
- c#中异常捕获,回滚
语法: try { 有可能出现错误的代码写在这里 } catch { 出错后的处理 } 如果try中的代码没有出错,则程序正常运行try中的内容后,不会执行catch中的内容, 如果try中的代码一但 ...
- Linq操作之Except,Distinct,Left Join 【转】
最近项目中用到了Linq中Except,Distinct,Left Join这几个运算,这篇简单的记录一下这几种情形. Except 基础类型使用Linq的运算很简单,下面用来计算两个集合的 ...
- vue-$watch属性方法
特性 https://www.cnblogs.com/widgetbox/p/8954162.html https://segmentfault.com/a/1190000012948175?utm_ ...
- Lua入门记录
学习资料 Lua入门和Lua高阶章节 Lua中文文档 阅读笔记,只是记录了知识点和一些注意点,详细的看上面提供的学习资料链接 Lua 基础数据类型 nil(空) boolean(布尔) Lua 中 n ...