Bayan 2015 Contest Warm Up C

在一块n*m的区域中有一块a*b的刷子,这块刷子只能向下or向右,扫过的区域为x

给出一块区域,问这个区域是否可以由某块刷子刷成,如果可以输出刷子最小面积,不可以则输出-1

 

思路:

      暴力枚举刷子的边长并验证,输出最小的刷子面积。

 

#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char str[1002][1002];
int n,m,ssa,ssb,sum,dpa[1002][1002],dpb[1002][1002],dp[1002][1002];
bool right(int loca,int locb,int lena,int lenb){
    if(locb+lenb-1>m)return 0;
    if(dpa[loca+lena-1][locb+lenb]-dpa[loca-1][locb+lenb]!=lena)return 0;
    return 1;
}
bool down(int loca,int locb,int lena,int lenb){
    if(loca+lena-1>n)return 0;
    if(dpb[loca+lena][locb+lenb-1]-dpb[loca+lena][locb-1]!=lenb)return 0;
    return 1;
}
bool check(int lena,int lenb){
    int loca=ssa,locb=ssb,i,j;
    if(ssa+lena-1>n||ssb+lenb-1>m)return 0;
    if(dp[loca+lena-1][locb+lenb-1]-dp[loca-1][locb+lenb-1]-dp[loca+lena-1][locb-1]+dp[loca-1][locb-1]!=lena*lenb)return 0;
    sum-=lena*lenb;
    while(1){
        bool flagr=0,flagl=0;
        if(right(loca,locb,lena,lenb))flagr=1;
        if(down(loca,locb,lena,lenb))flagl=1;
        if(flagl&&flagr){
            return 0;
        }
        if(!flagl&&!flagr){
            break;
        }
        if(flagr){
            sum-=lena;
            locb++;
        }
        if(flagl){
            sum-=lenb;
            loca++;
        }
    }
    if(sum!=0)return 0;
    return 1;
}
int main(){
    int i,j,k,tot;
    while(cin>>n>>m){
        for(i=1;i<=n;i++){
            cin>>str[i]+1;
        }
        if(n==1&&m==1){
            cout<<1<<endl;
            continue;
        }
        tot=0;
        bool flag=0;
        memset(dp,0,sizeof(dp));
        memset(dpa,0,sizeof(dpa));
        memset(dpb,0,sizeof(dpb));
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
                if(str[i][j]=='X'){
                    if(!flag)ssa=i,ssb=j;
                    flag=1;
                    tot++;
                    dp[i][j]++;
                    dpa[i][j]=dpa[i-1][j]+1;
                    dpb[i][j]=dpb[i][j-1]+1;
                }
            }
        }
        flag=0;
        int res=n*m;
        for(i=1;i<=n;i++){
            for(j=1;j<=m;j++){
                if(i*j>=res)continue;
                sum=tot;
                if(check(i,j)){
                    flag=1;
                    res=i*j;
                }
            }
        }
        if(!flag)cout<<-1<<endl;
        else cout<<res<<endl;
    }
    return 0;
}

 

你可能感兴趣的:(test)