cf475C

http://codeforces.com/contest/475/problem/C

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

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


const  int  maxn = 1008  ;
int   n ,  m ;
char  g[maxn][maxn]  ;
int   dp[maxn][maxn] ;

int   sum(int sx , int sy , int ex , int ey){
      return dp[ex][ey] - dp[sx-1][ey] - dp[ex][sy-1] + dp[sx-1][sy-1] ;
}

int   gao(int x , int y , int w , int h){
      while(1){
           if(x + w -1 > n || y + h -1 > m)  return 0 ;
           if(sum(x , y , x+w-1 , y+h-1) != w * h) return 0 ;
           if(sum(x+w , y, n , m) == 0 && sum(x , y+h , n , m) == 0) return 1 ;
           if(sum(x+w , y , n , y) > 0 && sum(x , y+h , x , m) > 0) return 0 ;
           if(sum(x+w , y , n , y) == 0) y++ ;
           else   x++ ;
      }
      return 1 ;
}

int   main(){

      int i , j  , t , sx , sy ;
      while(cin>>n>>m){
           for(i = 1 ; i <= n ; i++) scanf("%s" , g[i] + 1) ;

           memset(dp , 0 , sizeof(dp)) ;
           sx = n + 1 , sy = m + 1 ;

           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] + (g[i][j] == 'X') ;
                   if(g[i][j] == 'X'){
                       sx = std::min(sx , i) ;
                       sy = std::min(sy , j) ;
                   }
               }
           }

           t = 1<<30 ;

           for(i = 1 ; i <= n ; i++){
              for(j = 1 ; j <= m ; j++){
                   if(i * j >= t) continue ;
                   if(gao(sx , sy , i , j)) t = i * j ;
              }
           }

           if(t == (1<<30)) puts("-1") ;
           else             printf("%d\n" , t) ;

      }
      return 0  ;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值