Time Limit: 1000 MS Memory Limit: 131072 K
Description
Long time ago, a king occupied a vast territory.
Now there is a problem that he worried that he want to choose a largest square of his territory to build a palace. Can you help him?For simplicity, we use a matrix to represent the territory as follows:
0 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 0 0 0 1 0 0Every single number in the matrix represents a piece of land, which is a 1*1 square
1 represents that this land has been occupied 0 represents notObviously the side-length of the largest square is 2
InputThe first line of the input contains a single integer t (1≤t≤5) — the number of cases.
For each case The first line has two integers N and M representing the length and width of the matrix Then M lines follows to describe the matrix 1≤N,M≤1000Output
For each case output the the side-length of the largest square
Sample Input
2
5 5 0 0 0 0 0 0 1 0 1 0 1 1 0 1 0 0 1 1 0 0 0 0 1 0 0 5 5 0 0 0 0 0 0 1 0 1 0 1 1 1 1 0 0 1 1 0 0 0 0 1 0 0Sample Output
1
2#include#include #include #include #include #include //STL数值算法头文件#include #include #include #include #include //模板类头文件using namespace std;const int INF=1e9+7;const int maxn=1010;typedef long long ll;//单调栈//先做 poj 2559后再看单调栈可能会好理解一点int a[1010][1010];struct node{ int idx,num;//下标和延伸值};int main(){ int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { scanf("%d",&a[i][j]); if(a[i][j]) a[i][j]+=a[i-1][j]; } a[i][m+1]=-1; } int ans=-1; for(int i=1; i<=n; i++) { int top=0; node vis[1010]; for(int j=1; j<=m+1; j++) { if(top==0) { vis[top].idx=j,vis[top++].num=1; } else { printf("top=%d\n",top); int v=vis[top-1].idx,cont=0; while(top>0&&a[i][v]>=a[i][j]) { cont+=vis[top-1].num; if(cont>=a[i][v]) ans=max(ans,a[i][v]); top--; v=vis[top-1].idx; } vis[top].idx=j,vis[top++].num=cont+1; printf("vis[top].idx=%d vis[top].num=%d\n",vis[top-1].idx,vis[top-1].num); } } } printf("%d\n",ans); }}//暴力//先把每一列累加,类似于条形图,然后从每一行的开头开始遍历到每一行结束,//(不过是因为这一题的后台数据水,//暴力才能过,所以如果数据范围太大不推荐暴力)int mp[maxn][maxn];int main(){ int T; scanf("%d",&T); while(T--) { int n,m,x; memset(mp,0,sizeof(mp)); scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { scanf("%d",&x); if(x&&mp[i-1][j]) mp[i][j]=mp[i-1][j]+1; else mp[i][j]=x; } } int maxx=0; int k=1;//代表此时最大的面积 for(int i=1; i<=n; i++) { for(int j=1; j<=m; j++) { if(mp[i][j]>=k) { int p=0; for(; mp[i][p+j]>=k; p++);//每一行从头遍历到尾 if(p>=k) { maxx=k; k++; } } } } printf("%d\n",maxx); } return 0;}//动规//以每一个点作为正方形的右上角,//每次取四个角的最小值加一即为此时的最大面积(因为本题规定的每个矩形面积为1)//自己画图可以理解的int a[maxn][maxn];int dp[maxn][maxn];int main(){ int t; scanf("%d",&t); while(t--) { int n,m; scanf("%d%d",&n,&m); memset(dp,0,sizeof(dp)); for(int i=0; i