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 }

 

posted @ 2016-03-08 10:28  chenyushuo  阅读(241)  评论(0编辑  收藏  举报