题面

先把题目意思讲一下吧:

给一个 \(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的更多相关文章

  1. 1127: [POI2008]KUP

    1127: [POI2008]KUP https://lydsy.com/JudgeOnline/problem.php?id=1127 分析: 如果存在一个点大于等于k,小于等于2k的话,直接输出. ...

  2. [BZOJ1127][POI2008] KUP子矩阵

    Description 给一个n*n的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于[k,2k] Input 输入k n(n<2000)和一个n*n的地图 Output 输出矩形的左 ...

  3. bzoj1127: [POI2008]KUP

    Description 给一个n*n的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于[k,2k] Input 输入k n(n<2000)和一个n*n的地图 Output 输出矩形的左 ...

  4. bzoj1127[POI2008]KUP 悬线法

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

  5. 解题:POI 2008 Plot purchase

    题面 原来看过然后没做,结果板板把这道题改了改考掉了,血亏=.= 首先看看有没有符合条件的点.如果没有开始寻找解,先把所有的大于$2*k$的点设为坏点,然后求最大子矩形,只要一个最大子矩形的权值和超过 ...

  6. [BZOJ] 1127: [POI2008]KUP

    似曾相识的感觉 考虑另一个判断问题,给定一个k,问这个k是否可行 存在矩形和\(sum>2k\),则该矩阵不对判定做出贡献 存在矩形和\(sum\in [k,2k]\),则我们找到了一个解 于是 ...

  7. bzoj 1127 [POI2008]KUP——思路(悬线法)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1127 大于2*K的视为不能选的“坏点”.有单个格子满足的就直接输出. 剩下的都是<K的 ...

  8. [POI2008]KUP

    Description 给一个\(n\times n\)的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于[k,2k] Input 输入k n(n<2000)和一个\(n\times ...

  9. 【BZOJ-1127】KUP 悬线法 + 贪心

    1127: [POI2008]KUP Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 317  Solved: 11 ...

随机推荐

  1. 【Python】【demo实验7】【练习实例】【完全平方数相关】

    题目:一个整数,它加上100后是一个完全平方数,再加上168又是一个完全平方数,请问该数是多少? 程序分析:可填在百位.十位.个位的数字都是1.2.3.4.组成所有的排列后再去 掉不满足条件的排列. ...

  2. Docker 运行 MYSQL 数据库的总结

    公司里面要求做一个小demo 学习java相关的东西 然后使用了mysql数据库 很早之前做过mysql的容器化运行. 现在想想已经忘记的差不多了  所以这里总结一下 docker化运行mysql数据 ...

  3. 使用 WijmoJS 轻松实现撤消重做(Undo /Redo)

    使用 WijmoJS 轻松实现撤消重做(Undo /Redo) 在V2019.0 Update2 的全新版本中,WijmoJS能够轻松实现撤消和重做操作,使Web应用程序的使用更加友好.更加高效. 不 ...

  4. Android笔记01--手机振动

    一.android任务栈  不懂? 栈:先进后出 队列:先进先出 任务栈Task中:打开一个Activity叫进栈 关闭一个activit出栈 任务栈是用来维护Activity的.是用来维护用户的操作 ...

  5. MySQL中的数据类型 [数值型、字符串型、时间日期型]

    MySQL中的数据类型 [数值型.字符串型.时间日期型] MySQL中各数据类型 1. 数值类型(整型) 类型 数据大小 类型 (无符号:unsigned) 数据大小 存储空间 tinyint -12 ...

  6. 【LOJ】#3093. 「BJOI2019」光线

    LOJ#3093. 「BJOI2019」光线 从下到上把两面镜子合成一个 新的镜子是\((\frac{a_{i}a_{i + 1}}{1 - b_{i}b_{i + 1}},b_{i} + \frac ...

  7. Java实现二叉树地遍历、求深度和叶子结点的个数

    一.分析 二叉树是n个结点所构成的集合,它或为空树,或为非空树.对于非空树,它有且仅有一个根结点,且除根结点以外的其余结点分为两个互不相交的子集,分别称为左子树和右子树,它们本身又都是二叉树. 显而易 ...

  8. LINK : fatal error LNK1104: cannot open file的解决方法

    结果是编译时通过了,但连接(F7)时却显示: LINK : fatal error LNK1104: cannot open file“Debug/1.exe” ============== 上一次运 ...

  9. winform中如何在多线程中更新UI控件--ListView实时显示执行信息

    1.在winform中,所有对UI的操作,都得回到UI线程(主线程)上来,才不会报错 线程间操作无效: 从不是创建控件的线程访问它. 2.在winform中,允许通过Control.invoke对控件 ...

  10. [IOI2005]Riv河流

    题目链接:洛谷,BZOJ 前置知识:莫得 题解 直接考虑dp.首先想法是设状态 \(dp[u][i]\) 表示u的子树内建 \(i\) 个伐木场且子树内木头都运到某个伐木场的最小花费.发现这样的状态是 ...