bzoj1127: [POI2008]KUP

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

题解:

http://blog.csdn.net/popoqqq/article/details/44625423

code:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long int64;
 8 char ch;
 9 bool ok;
10 void read(int &x){
11     for (ok=0,ch=getchar();!isdigit(ch);ch=getchar()) if (ch==‘-‘) ok=1;
12     for (x=0;isdigit(ch);x=x*10+ch-‘0‘,ch=getchar());
13     if (ok) x=-x;
14 }
15 const int maxn=2005;
16 int k,n,a[maxn][maxn],head,tail,last,h[maxn],top,l[maxn],r[maxn];
17 int64 sum[maxn][maxn];
18 int64 calc(int x,int y,int xx,int yy){return sum[xx][yy]-sum[xx][y-1]-sum[x-1][yy]+sum[x-1][y-1];}
19 struct Data{
20     int val,id;
21 }que[maxn],stack[maxn];
22 void output(int x,int y,int xx,int yy){
23     while (calc(x,y,xx,yy)>k*2){
24         if (x==xx) y++;
25         else if (calc(x+1,y,xx,yy)>=k) x++;
26         else xx--;
27     }
28     printf("%d %d %d %d\n",y,x,yy,xx);
29     exit(0);
30 }
31 void work(int x){
32     /*head=1,tail=0,last=1;
33     for (int i=1;i<=n;i++){
34         while (head<=tail&&que[tail].val>=h[i]) tail--;
35         que[++tail]=(Data){h[i],i};
36         while (head<=tail&&que[head].val==0) last=que[head++].id+1;
37         if (head<=tail&&calc(x-que[head].val+1,last,x,i)>=k) output(x-que[head].val+1,last,x,i);
38     }*/
39     top=0;
40     for (int i=1;i<=n+1;i++){
41         while (top&&stack[top].val>h[i]) r[stack[top--].id]=i-1;
42         stack[++top]=(Data){h[i],i};
43     }
44     top=0;
45     for (int i=n;i>=0;i--){
46         while (top&&stack[top].val>h[i]) l[stack[top--].id]=i+1;
47         stack[++top]=(Data){h[i],i};
48     }
49     for (int i=1;i<=n;i++)
50         if (h[i]) if (calc(x-h[i]+1,l[i],x,r[i])>=k) output(x-h[i]+1,l[i],x,r[i]);
51 }
52 int main(){
53     read(k),read(n);
54     for (int i=1;i<=n;i++) for (int j=1;j<=n;j++){
55         read(a[i][j]),sum[i][j]=sum[i][j-1]+a[i][j];
56         if (k<=a[i][j]&&a[i][j]<=k*2){printf("%d %d %d %d\n",j,i,j,i);return 0;}
57     }
58     for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) sum[i][j]+=sum[i-1][j];
59     for (int i=1;i<=n;i++){
60         for (int j=1;j<=n;j++) h[j]=a[i][j]>k*2?0:h[j]+1;
61         work(i);
62     }
63     puts("NIE");
64     return 0;
65 }
时间: 2024-12-09 22:52:47

bzoj1127: [POI2008]KUP的相关文章

[BZOJ1127][POI2008] KUP子矩阵

Description 给一个n*n的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于[k,2k] Input 输入k n(n<2000)和一个n*n的地图 Output 输出矩形的左上和右下的列-行坐标 或NIE Sample Input inputdata14 31 1 11 9 11 1 1inputdata28 41 2 1 325 1 2 14 20 3 33 30 12 2 Sample Output outputdata1NIEoutputdata22 1 4 2 题解(

bzoj1127[POI2008]KUP 悬线法

Time Limit: 10 Sec  Memory Limit: 162 MBSec  Special JudgeSubmit: 485  Solved: 174[Submit][Status][Discuss] Description 给一个n*n的地图,每个格子有一个价格,找一个矩形区域,使其价格总和位于[k,2k] Input 输入k n(n<2000)和一个n*n的地图 Output 输出矩形的左上和右下的列-行坐标或NIE Sample Input inputdata1 4 3 1

1127: [POI2008]KUP

1127: [POI2008]KUP https://lydsy.com/JudgeOnline/problem.php?id=1127 分析: 如果存在一个点大于等于k,小于等于2k的话,直接输出. 否则把点分成两类,一类是<k的,另一类是大于2k的,大于2k的一定没用. 然后找一个全部由小于2k的点中组成一个的矩形(悬线法),这个矩形有三种情况:1.<k,没用:2.大于等于k,小于等于2k,输出:3.大于2k,它的子矩阵中一定存在一个合法的矩阵(因为每个元素都是<k的,所以增加一个元

POI2008 题解

POI2008 完结(′?_?`)撒花! 海报PLA 单调栈裸题! 激光发射器SZK 光路可逆? 然后证一下发射器与接收器两两对应? 砖块Klo 区间中值! 可用树状数组水过... 将高度 \( h \) 的值域作为树状数组维护的序列,维护一下前缀数量与前缀和即可. BLO 求割点裸题! Sta so easy 的树上DP! CLO 蜜汁构造... Tro 草稿题... 把差积分开算,求和 枪战Maf 有向仙人掌? naive! 贪心构造即可(<--口胡的) 正解还要分好多种情况? 账本BBB

BZOJ1124: [POI2008]枪战Maf

1124: [POI2008]枪战Maf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 501  Solved: 200[Submit][Status][Discuss] Description 有n个人,每个人手里有一把手枪.一开始所有人都选定一个人瞄准(有可能瞄准自己).然后他们按某个顺序开枪,且任意时刻只有一个人开枪.因此,对于不同的开枪顺序,最后死的人也不同. Input 输入n人数<1000000 每个人的aim Output 你要求最

1131: [POI2008]Sta

1131: [POI2008]Sta Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 783  Solved: 235[Submit][Status] Description 给出一个N个点的树,找出一个点来,以这个点为根的树时,所有点的深度之和最大 Input 给出一个数字N,代表有N个点.N<=1000000 下面N-1条边. Output 输出你所找到的点,如果具有多个解,请输出编号最小的那个. Sample Input 8 1 4 5 6

BZOJ 1113: [Poi2008]海报PLA

题目 1113: [Poi2008]海报PLA Time Limit: 10 Sec  Memory Limit: 162 MB Description N个矩形,排成一排. 现在希望用尽量少的矩形海报Cover住它们. Input 第一行给出数字N,代表有N个矩形.N在[1,250000] 下面N行,每行给出矩形的长与宽.其值在[1,1000000000]2 1/2 Postering Output 最少数量的海报数. Sample Input 5 1 2 1 3 2 2 2 5 1 4 Sa

AC日记——[POI2008]BLO-Blockade 洛谷 [POI2008]BLO-Blockade

[POI2008]BLO-Blockade 思路: tarjan: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 100005 #define maxm 500005 #define ll long long ll Count[maxn],E[maxm<<1],V[maxm<<1],head[maxn],cnt; ll size[maxm],dfn[maxn],n,m,tot,low[max

bzoj1112[POI2008]砖块Klo*

bzoj1112[POI2008]砖块Klo 题意: N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:丢掉某柱砖的一块砖.给某柱加上一块砖,现在希望用最小次数的动作完成任务.N≤100000 题解: 设一个区间长度为k,其中位数为a,比a小的元素个数为b,和为c:比a大的元素个数为d,和为e.则题目要求维护一个长度为k的滑动窗口,能求出它的b*a-c+e-d*a.故用一个维护sum,size两个值的treap来维护.然而似乎我想复杂了?比所有人代码都大1k!注意要开long