身为魔法少女的一员,学姐(头还在哦)在最后一战之后便退隐了。她决定用她剩余的魔法去圈一块矩形花园。但是有一些土地会使学姐的魔法失效(即边不可以跨越这些土地)。现在学姐想知道在这块N*M的土地上她可以获得的最大花园面积。(单位格面积为1).在这块N*M的图中,”.”表示学姐可以施法,”X”表示会失效。(1<=N,M<=200)。
Input
输入为多组样例,第一行为N和M,下面N*M描述这个土地。
Output
输出多行,每行为麻美学姐可以获得的最大花园面积。
Sample Input
5 6 ...... ..X..X X..X.. ...... ..X...
Sample Output
16
HINT
如上样例,假设麻美学姐的魔法为F,那么她圈地的方式是
.FFFF.
.FX.FX
XF.XF.
.FFFF.
..X...
思路:
先把数据转换成01矩阵,然后维护每一行的前缀和。接下来就可以用O(1)的时间复杂度查询一段数组的和。若一段数组的和为0,则没有X,否则就有X。
枚举矩形的左右两列,然后开始搜索矩形的上下两行。在行向下滑动的过程用一个值维护矩形的上边的行号。若找到一个全0行,先判断是否已经存在一个合法的矩形的上边,若不存在则用该全0行的行号更新上边的行号,若存在上边,则该行为矩形的下边,这时就得到了一个合法的矩形,计算面积后去更新最大面积的值。
#include<stdio.h>
#define NOT_EXIST -1
int map[204][204];
void initial_matrix(int n,int m){
getchar();
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
if(getchar()==‘.‘) map[i][j]=0;
else map[i][j]=1;
if(j>0) map[i][j]+=map[i][j-1];
}
getchar();
}
// for(int i=0;i<n;++i){
// for(int j=0;j<m;++j){
// printf("%d",map[i][j]);
// }
// printf("\n");
// }
}
inline bool zero_point(int row,int col){
if(col-1<0&&(map[row][col]==0)) return true;
else if(col-1>=0&&(map[row][col]-map[row][col-1]==0)) return true;
else return false;
}
inline bool blank_line(int row,int col_left,int col_right){
if(col_left-1<0&&(map[row][col_right]==0)) return true;
else if(col_left-1>=0&&(map[row][col_right]-map[row][col_left-1]==0)) return true;
else return false;
}
void open(){
freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
}
int main(int argc,char **argv){
int n,m;
// open();
while(scanf("%d%d",&n,&m)!=EOF){
initial_matrix(n,m);
int rectangle_top_edge;
int max_area=0;
for(int col_left=0;col_left<m;++col_left){
for(int col_right=col_left; col_right < m; ++col_right){
rectangle_top_edge=NOT_EXIST;
for(int row=0;row < n; ++row){
// printf("row=%d col_left%d:%d col_right%d:%d\n",row,col_left,zero_point(row,col_left),col_right,zero_point(row,col_right));
if(zero_point(row,col_left) && zero_point(row,col_right)){
if(blank_line(row,col_left,col_right)){
if(rectangle_top_edge==NOT_EXIST){
rectangle_top_edge=row;
if(col_right-col_left+1 > max_area) {
max_area=col_right-col_left+1;
// printf("rectangle_top_edge=%d row=%d col_left=%d col_right=%d max_area=%d\n",rectangle_top_edge,row,col_left,col_right,max_area);
}
}else {
if((row-rectangle_top_edge+1)*(col_right-col_left+1)>max_area){
max_area= (row-rectangle_top_edge+1)*(col_right-col_left+1);
// printf("rectangle_top_edge=%d row=%d col_left=%d col_right=%d max_area=%d\n",rectangle_top_edge,row,col_left,col_right,max_area);
}
}
}
}else{
rectangle_top_edge=NOT_EXIST;
}
}
}
}
printf("%d\n",max_area);
}
return 0;
}