Finding Seats HDU - 1937
原题链接
考察:双指针+枚举
很经典的思路,但蒟蒻不会...
错误思路:
二分面积,然后发现需要枚举面积的约数,配合多组样例会TLE
思路:
枚举第\(i,j\)行,在\([i,j]\)之间作双指针求\(>=k\)的最小面积.
Code
#include <iostream>
#include <cstring>
using namespace std;
const int N = 310;
int n, m, k;
int mp[N][N];
char op[N];
int query(int a,int b,int x,int y)
{
return mp[x][y] - mp[a - 1][y] - mp[x][b - 1] + mp[a - 1][b - 1];
}
int solve()
{
int res = 0x3f3f3f3f;
for (int i = 1; i <= n;i++)
for (int j = i; j <= n;j++)//i~j琛?
{
int maxn = 400;
bool ok = 0;
for (int l = 1, r = 1; l <= m; l++)
{
while(r<=m&&query(i,l,j,r)<k)
r++;
if(query(i,l,j,r)>=k)
maxn = min(r - l+1, maxn),ok = 1;
if(r>m) break;
}
if(ok) res = min(res, maxn * (j - i+1));
}
return res;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&k)!=EOF&&(n+m+k))
{
memset(mp, 0, sizeof mp);
for (int i = 1; i <= n;i++)
{
scanf("%s", op+1);
for(int j= 1 ;j <= m;j++)
{
if(op[j]=='.') mp[i][j]++;
mp[i][j] += mp[i - 1][j] + mp[i][j - 1] - mp[i - 1][j - 1];
}
}
printf("%d\n", solve());
}
return 0;
}