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