HDU-1937 Finding Seats 2D Ruler Method

  • Finding Seats
  • Meaning of the question
    Find a rectangle, the number of seats in the rectangle needs to be greater than or equal to K, find the area of ​​the smallest rectangle that meets the conditions
  • Ideas I
    originally thought about violence and pruning, but the worst complexity is still 1e8, which is decisive. Later, I thought of the ruler method, but this ruler method is two-dimensional, and it is easy to write as long as it is slightly processed.
    We traverse the upper and lower bounds of the rectangle, and then take the ruler to find the optimal solution that satisfies the conditions.
    Example 1
    In the figure, i points to the upper boundary of the rectangle, and j points to the lower boundary. l and r point to columns. When r is shifted to the right, sum+=3, when l is shifted to the right, sum-=1. According to the comparison between sum and K, the direction of movement of l is determined when sum<K. Move r to the right, otherwise, move l to the right. For l, r each shift of the change value of sum by one column, we can prefix and sum each column according to the space, so that the change value can be calculated by o(1) ( sum [j] [r] − sum [i] [r ] Or sum [j] [l] − sum [i] [l] sum[j][r]-sum[i][r] or sum[j][l]-sum[i][l]sum[j][r]S U m [ I ] [ R & lt ] or by S U m [ J ] [ L ]s u m [ i ] [ l ] ). The complexity of a single set of examples is o(1e6)
  • Code
#pragma GCC optimize(2)
#include<bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long ul;
typedef unsigned long long ull;
#define pi acos(-1.0)
#define e exp(1.0)
#define pb push_back
#define mk make_pair
#define fir first
#define sec second
#define scf scanf
#define prf printf
typedef pair<ll,ll> pa;
const ll INF=0x3f3f3f3f3f3f3f3f;
const ll MAX_R=360;
char Ma[MAX_R][MAX_R];
ll R,C,K;
ll sum[MAX_R][MAX_R];
int main()
{
    
    
//  freopen(".../.txt","w",stdout);
//  freopen(".../.txt","r",stdin);
	ios::sync_with_stdio(false);
	ll i,j,k,x,y;
	while(cin>>R>>C>>K&&(R||C||K)){
    
    
		for(i=1;i<=R;i++)
		cin>>Ma[i]+1;
		for(j=1;j<=C;j++){
    
    //前缀和预处理
			sum[0][j]=0;
			for(i=1;i<=R;i++){
    
    
				sum[i][j]=sum[i-1][j];
				if(Ma[i][j]=='.')
				sum[i][j]++;
			}
		}
//		cout<<do_(1,1,2,3)<<endl;
		ll ans=INF,l,r;
		for(i=1;i<=R;i++){
    
    
			for(j=i;j<=R;j++){
    
    
				if((j-i+1)>ans)//单列的面积已经比已知答案大了,跳过
				break;
				l=r=1;
				ll tmp=0;
				bool flag=1;
				while(l<=r&&r<=C){
    
    
					if(flag)
					tmp+=(sum[j][r]-sum[i-1][r]);
					if(tmp<K){
    
    
						r++;
						flag=1;
					}
					else{
    
    
						ans=min(ans,(j-i+1)*(r-l+1));
//						cout<<"("<<i<<","<<l<<")"<<"("<<j<<","<<r<<")"<<endl;
						tmp-=(sum[j][l]-sum[i-1][l]);
						l++;
						flag=0;
						if(l>r){
    
    
							r=l;
							flag=1;
						}
					}
				}
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43311695/article/details/108676249