First Bangladeshi Contest 20122013 Season[7月12日暑假集训]

比赛地址:http://acm.hust.edu.cn:8080/judge/contest/view.action?cid=9380#overview

D .Draw and Score

  N个点的最终排列是一棵完全二叉树,没证明,凭直觉。假设N个点排成的完全二叉树有k层,那么前k-1层是满二叉树,可以先算出满二叉树的score,再处理最后一层。具体方法画个草图不难看出规律。

K .K-Neutral Rectangles

  求一个矩阵中最大的一个子矩阵的大小,子矩阵满足相邻元素之间的差的绝对值小于等于K

  一行一行处理,维护两个数组h[1000]b[1000],每处理一行更新一次两个数组。处理第i行时,h[ j ]表示第i行第j列元素能向上“上升”的最大高度(相邻元素差的绝对值小于K)。B[ j ]表示第j列和j-1列能“兼容上升”的最大高度。h[ j ]可以更新maxArea,表示单独的一列构成的矩阵。b[ j ]数组表示以第i行为最后一行,构成的矩阵。第j个元素向前能“前推”多长,高度多高,可以通过b[ ]数组来得到。具体处理可以用栈来优化。

 

View Code
  1 //zzy2012.7.12AC
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<string>
  6 #include<cmath>
  7 #include<iostream>
  8 #include<algorithm>
  9 #include<map>
 10 #include<vector>
 11 #include<queue>
 12 #define sf scanf
 13 #define pf printf
 14 #define pfn printf("\n");
 15 #define ll long long
 16 #define INF 0x7fffffff
 17 
 18 using namespace std;
 19 
 20 int n,m,k,area,a[1000][1000],b[1000],h[1000],top,stack[1000],stack2[1000];
 21 
 22 void D(){
 23     for(int i=0; i<n; i++){
 24         for(int j=0; j<m; j++){
 25             if(i>=1 && abs(a[i][j]-a[i-1][j])<=k)
 26                 h[j]++;
 27             else
 28                 h[j]=1;
 29             if(h[j]>area)
 30                 area = h[j];
 31         }
 32         for(int j=1; j<m; j++){
 33             if(abs(a[i][j]-a[i][j-1])<=k){
 34                 b[j]++;
 35                 if(b[j]>min(h[j],h[j-1]))
 36                     b[j] = min(h[j],h[j-1]);
 37             }
 38             else
 39                 b[j]=0;
 40         }
 41         top=0;
 42         for(int j=1; j<m; j++){
 43             if(top == 0){
 44                 if(b[j]>0){
 45                     stack[top] = b[j];
 46                     stack2[top++] = j;
 47                 }
 48             }
 49             else if(b[j]>0){
 50                 if(b[j]>stack[top-1]){
 51                     stack[top] = b[j];
 52                     stack2[top++] = j;
 53                 }
 54                 else if(b[j]<stack[top-1]){
 55                     while(top>0 && b[j]<stack[top-1]){
 56                         if(area < (j - stack2[top-1] + 1)*stack[top-1])
 57                             area = (j - stack2[top-1] + 1)*stack[top-1];
 58                         top--;
 59                     }
 60                     if(top == 0 || b[j]>stack[top-1])
 61                         stack[top++]=b[j];
 62                 }
 63             }
 64             else{
 65                 while(top>0){
 66                 if(area < (j - stack2[top-1] + 1)*stack[top-1])
 67                     area = (j - stack2[top-1] + 1)*stack[top-1];
 68                     top--;
 69                 }
 70             }
 71         }
 72         while(top>0){
 73             if(area < (m - stack2[top-1] + 1)*stack[top-1])
 74                 area = (m - stack2[top-1] + 1)*stack[top-1];
 75             top--;
 76         }
 77     }
 78 }
 79 
 80 int main()
 81 {
 82     int t,T;
 83     cin>>T;
 84     for(t=1; t<=T; t++){
 85         sf("%d %d %d",&n,&m,&k);
 86         for(int i=0; i<n; i++){
 87             for(int j=0; j<m; j++){
 88                 sf("%d",&a[i][j]);
 89             }
 90         }
 91         for(int j=0; j<m; j++){
 92             b[j]=0;
 93             h[j]=0;
 94         }
 95         area=0;
 96         D();
 97         printf("Case %d: %d\n",t,area);
 98     }
 99     return 0;
100 }

 

 

原文地址:https://www.cnblogs.com/Lattexiaoyu/p/2588941.html