Finding Seats
题意 找一个长方形,长方形中中的座位数量需要大于等于K,求满足条件的最小的长方形的面积
思路 原先想的是暴力加上剪枝,但是最坏复杂度还是1e8,果断T了。之后想到尺取法,只不过这种尺取法是二维的,只要稍加处理还是很好写的。 我们遍历长方形的上下界,然后尺取的求满足条件的最优解。 图中i指向长方形的上边界,j指向下边界。l,r指向的都是列,当r右移的时候sum+=3,当l右移的时候sum-=1,根据sum和K的大小比较确定l,r的移动方向当sum<K时,将r右移,否则,将l右移。对于l,r每移动一列sum的变化值我们可以对每一列根据空位进行前缀求和,这样变化值就可以o(1)的求出来( s u m [ j ] [ r ] − s u m [ i ] [ r ] 或 者 s u m [ j ] [ l ] − s u m [ i ] [ l ] sum[j][r]-sum[i][r]或者sum[j][l]-sum[i][l] s u m [ j ] [ r ] − s u m [ i ] [ r ] 或 者 s u m [ j ] [ l ] − s u m [ i ] [ l ] )。单组样例的复杂度是o(1e6)
代码
#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 ( )
{
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] ++ ;
}
}
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 ) ) ;
tmp- = ( sum[ j] [ l] - sum[ i- 1 ] [ l] ) ;
l++ ;
flag= 0 ;
if ( l> r) {
r= l;
flag= 1 ;
}
}
}
}
}
cout<< ans<< endl;
}
return 0 ;
}