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;
}

posted @ 2021-07-09 22:44  acmloser  阅读(21)  评论(0编辑  收藏  举报