解题:POI 2008 Plot purchase

题面

原来看过然后没做,结果板板把这道题改了改考掉了,血亏=。=

首先看看有没有符合条件的点。如果没有开始寻找解,先把所有的大于$2*k$的点设为坏点,然后求最大子矩形,只要一个最大子矩形的权值和超过$2*k$则它的一个子矩形一定可以成为解。因为这时所有点都小于$k$,这个最大子矩形既然权值和超过$2*k$那么一定是有一部分落在所求的区间中,然后逐行/列枚举切一下是一定有解的。

注意最大子矩形的边界(为什么你们的最大子矩形都要做两遍啊=。=)

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int N=2005;
 6 struct a
 7 {
 8     int xx,yy,zz;
 9 }stk[N],str;
10 long long fsum[N][N];
11 int mapp[N][N],dp[N][N];
12 long long n,k,rd,top,ans;
13 void gun(){exit(0);}
14 long long getsum(int x1,int y1,int x2,int y2)
15 {
16     return fsum[x2][y2]-fsum[x1-1][y2]-fsum[x2][y1-1]+fsum[x1-1][y1-1];
17 }
18 void check(int x1,int y1,int x2,int y2)
19 {
20     if(x1>x2||y1>y2) return ;
21     long long sum=getsum(x1,y1,x2,y2); if(sum<k) return ; 
22     if(sum>=k&&sum<=2*k) printf("%d %d %d %d",y1,x1,y2,x2),gun();
23     for(int i=x1+1;i<=x2;i++)
24     {
25         long long t1=getsum(i,y1,x2,y2),t2=sum-t1;
26         if(t1>=k&&t1<=2*k) printf("%d %d %d %d",y1,i,y2,x2),gun();
27         else if(t2>=k&&t2<=2*k) printf("%d %d %d %d",y1,x1,y2,i),gun();
28     }
29     return ;
30 }
31 int main ()
32 {
33     scanf("%lld%lld",&k,&n);
34     for(int i=1;i<=n;i++)
35         for(int j=1;j<=n;j++)
36         {
37             scanf("%lld",&rd),mapp[i][j]=(rd<=2*k),fsum[i][j]=rd;
38             if(rd<=2*k&&rd>=k) printf("%d %d %d %d",j,i,j,i),gun();
39         }
40     for(int i=1;i<=n;i++)
41         for(int j=1;j<=n;j++)
42         {
43             fsum[i][j]+=fsum[i-1][j]+fsum[i][j-1]-fsum[i-1][j-1];
44             if(mapp[i][j]) dp[i][j]=dp[i-1][j]+1; 
45         }
46     for(int i=1;i<=n;i++)
47         for(int j=1;j<=n+1;j++)
48         {
49             str.xx=j,str.yy=dp[i][j],str.zz=i;
50             if(!top||stk[top].yy<str.yy) stk[++top]=str;
51             else
52             {
53                 int tmp=j;
54                 while(top&&stk[top].yy>=str.yy) 
55                     check(stk[top].zz-stk[top].yy+1,stk[top].xx,stk[top].zz,j-1),tmp=stk[top--].xx;
56                 str.xx=tmp,stk[++top]=str;
57             }
58         }
59     printf("NIE");
60     return 0;
61 }
View Code

猜你喜欢

转载自www.cnblogs.com/ydnhaha/p/9755841.html
今日推荐