Finding Seats HDU - 1937(尺取+容斥定理)

题意:有一个矩形方阵,标有'.'和'X',  '.'表示空地0,'X'表示被占用1;求出包含空地0的个数不少于K的面积最小的子矩阵的面积;

开始直接套用容斥定理写了个四层循环,果然超时了;

固定矩阵一边的长度,尺取法截取另一边的长度;

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
int R, C, K;
char mp[310][310];
int empty[310][310], sum[30][310];
int main(){
	while(scanf("%d%d%d", &R, &C, &K), R||C||K){
		for(int i=1; i<=R; i++){
			scanf("%s", mp[i]+1);
		}
		for(int i=1; i<=R; i++){
			for(int j=1; j<=C; j++){
				if(mp[i][j]=='.') empty[i][j]=1;
				else empty[i][j]=0;
				sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+empty[i][j];
			}
		}
		int ans=INF;
		for(int i=1; i<=R; i++){
		for(int j=i; j<=R; j++){
		for(int k=1, m=1; k<=C; k++){
			while(sum[j][m]-sum[i-1][m]-sum[j][k-1]+sum[i-1][k-1]<K&&m<C) m++;
			if(sum[j][m]-sum[i-1][m]-sum[j][k-1]+sum[i-1][k-1]>=K){
				ans=min(ans, (j-i+1)*(m-k+1));
			}
		}
		}
		}
		printf("%d\n", ans);
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sirius_han/article/details/81005173