【难】【DP】计算bool矩阵中,仅包含1的最大矩形和最大正方形

来源:互联网 发布:穷游软件 编辑:程序博客网 时间:2024/04/27 22:51

题目:EPI


class record{public:int right;//如果一个点是1,则记录该点右边有多少个连续的1(包括该点本身)int down;//如果一个点是1,则记录该点下边有多少个连续的1(包括该点本身)record(){}record(int r,int d):right(r),down(d){}};//计算最大矩形区域int find_largest_rectangle(const vector<vector<bool>> &A){if(A.empty() || A[0].empty())return -1;int rows=A.size(),cols=A[0].size();vector<vector<record>> m(rows,vector<record>(cols));for(int i=rows-1;i>=0;i--){for(int j=cols-1;j>=0;j--){if(A[i][j]){int r=j==cols-1?1:m[i][j+1].right+1;int d=i==rows-1?1:m[i+1][j].down+1;m[i][j]=record(r,d);}elsem[i][j]=record(0,0);}}int res=0;for(int i=rows-1;i>=0;i--){for(int j=cols-1;j>=0;j--){if(A[i][j] && m[i][j].down*m[i][j].right>res){int min_r=m[i][j].right;for(int k=0;k<m[i][j].down;k++){min_r=min(min_r,m[i+k][j].right);int tmp=(k+1)*min_r;res=max(res,tmp);}}}}return res;}//计算最大正方形区域int find_largest_square(const vector<vector<bool>> &A){if(A.empty() || A[0].empty())return -1;int rows=A.size(),cols=A[0].size();vector<vector<record>> m(rows,vector<record>(cols));for(int i=rows-1;i>=0;i--){for(int j=cols-1;j>=0;j--){if(A[i][j]){int r=j==cols-1?1:m[i][j+1].right+1;int d=i==rows-1?1:m[i+1][j].down+1;m[i][j]=record(r,d);}elsem[i][j]=record(0,0);}}int res=0;//side记录一个点作为正方形的左上角时,所能获得的最大边长的正方形vector<vector<int>> side(rows,vector<int>(cols,0));for(int i=rows-1;i>=0;i--){for(int j=cols-1;j>=0;j--){if(A[i][j]){int s=min(m[i][j].right,m[i][j].down);if(i<rows-1 && j<cols-1)s=min(s,side[i+1][j+1]+1);side[i][j]=s;res=max(res,s*s);}}}return res;}

相关题型:《程序员面试金典》P345

给定一个bool类型的方阵,设计一个算法,找出四条边皆为1的最大子方阵。

class record{public:int right;//如果一个点是1,则记录该点右边有多少个连续的1(包括该点本身)int down;//如果一个点是1,则记录该点下边有多少个连续的1(包括该点本身)record(){}record(int r,int d):right(r),down(d){}};//矩阵中以点A[row][col]为左上角、边长为side的正方形class square{public:int row,col;int side;square(int r,int c,int s):row(r),col(c),side(s){}};bool Issquare(const vector<vector<bool>> &A,const vector<vector<record>> &m,const int row,const int col,const int side){if(m[row+side-1][col].right<side)return false;if(m[row][col+side-1].down<side)return false;return true;}square find_largest_square_one_encircle(const vector<vector<bool>> &A){square res(-1,-1,-1);if(A.empty() || A.size()!=A[0].size())return res;int n=A.size();vector<vector<record>> m(n,vector<record>(n));for(int i=n-1;i>=0;i--){for(int j=n-1;j>=0;j--){if(A[i][j]){int r=j==n-1?1:m[i][j+1].right+1;int d=i==n-1?1:m[i+1][j].down+1;m[i][j]=record(r,d);}elsem[i][j]=record(0,0);}}for(int i=n-1;i>=0;i--){for(int j=n-1;j>=0;j--){if(A[i][j]){int side=min(m[i][j].right,m[i][j].down);if(side<=res.side)continue;while(side>res.side){if(Issquare(A,m,i,j,side)){res.row=i;res.col=j;res.side=side;break;}elseside--;}}}}return res;}

测试代码:

bool a[4][4]={{0,0,1,0},{0,1,1,1},{1,1,1,1},{0,1,1,1}};vector<vector<bool>> A(4,vector<bool>(4));for(int i=0;i<4;i++)for(int j=0;j<4;j++)A[i][j]=a[i][j];cout<<find_largest_rectangle(A);




0 0
原创粉丝点击