HDU_1937_Finding Seats

原题地址
简单说一下题意,题中定义的那个要求的值是能包含k的点的最小的子矩阵的面积,考试的时候没想出来,一看到题就蒙了,考完回来查题解原来是用尺取法,然后看了看思路,自己写了一发,简单说一下思路,就是先求出每个点道最左上角点之间有多少个点,然后枚举上界和下界,对上界下界之间的尺取就行了.

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
using namespace std;
int rec[500][500];
bool cal(int s,int e,int h1,int h2,int t){  //计算上界和下界,左右端点之间的点数是否大于k
    if(rec[h1][e]-rec[h1][s]-rec[h2][e]+rec[h2][s]>=t){
        return true;
    }
    else{
        return false;
    }
}
int main(){
    int n,m,k,h;
    while(~scanf("%d%d%d",&n,&m,&k)){
        if(n==0&&m==0&&k==0){
            break;
        }
        char map[500][500];
        int i,j,mins=99999999;
        for(i=1;i<=n;i++){
            scanf("%s",map[i]+1);
        }
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                rec[i][j]=rec[i][j-1];
                if(map[i][j]=='.'){
                    rec[i][j]++;
                }
            }
        }
        for(i=1;i<=m;i++){
            for(j=1;j<=n;j++){
                rec[j][i]=rec[j][i]+rec[j-1][i];
            }
        }
//        for(i=1;i<=n;i++){  //Debug
//            for(j=1;j<=m;j++){
//                printf("%d ",rec[i][j]);
//            }
//            printf("\n");
//        }
        //int s1,s2;
        for(i=0;i<=n;i++){   //枚举上界
            for(j=i+1;j<=n;j++){   //枚举下界
                int end=0;
                for(h=1;h<=m;h++){   //枚举列
                    if(rec[j][h]-rec[i][h]>=k){
                        while(cal(end, h, j, i, k)){
                            mins=min(mins,(j-i)*(h-end));
                            end++;
                        }
                    }
                }
            }
        }
        printf("%d\n",mins);
        memset(rec, 0, sizeof(rec));
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值