当前位置: 代码迷 >> 综合 >> hdu1937 Finding Seats(尺取)
  详细解决方案

hdu1937 Finding Seats(尺取)

热度:8   发布时间:2024-03-06 13:31:04.0

题意:

给定n*m的图,和一个整数k,
图由’X‘和’.‘组成,现在要求你找到一个面积最小的子矩阵,满足子矩阵中的’.'不少于k个。
输出最小面积。

数据范围:n,m<=300,k<=n*m

解法:

考虑1*m的矩阵,如果要求找到一个最小的子矩阵,满足不少于k个,
可以直接尺取。

那么n*m怎么做呢,枚举行i和行j,将[i,j]行合并为一行,每一列是[i,j]列的权值和。
然后就变成上面的情况了,进行尺取即可。

枚举i,j的复杂度为O(n2),尺取O(n),总复杂度O(n3)

code:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define ll long long
#define PI pair<int,int>
const int maxm=305;
char s[maxm][maxm];
int sum[maxm][maxm];
int temp[maxm];
int a[maxm];
int n,m,k;
signed main(){
    ios::sync_with_stdio(0);while(cin>>n>>m>>k){
    if(!(n+m+k))break;for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
    cin>>s[i][j];}}for(int i=1;i<=n;i++){
    for(int j=1;j<=m;j++){
    sum[i][j]=sum[i][j-1]+sum[i-1][j]-sum[i-1][j-1]+(s[i][j]=='.');}}int ans=n*m;for(int i=1;i<=n;i++){
    for(int j=i;j<=n;j++){
    for(int t=1;t<=m;t++){
    temp[t]=sum[j][t]-sum[i-1][t];}int p=1;for(int t=1;t<=m;t++){
    while(temp[t]-temp[p-1]>=k){
    ans=min(ans,(j-i+1)*(t-p+1));p++;}}}}cout<<ans<<endl;}return 0;
}

  相关解决方案