king's trouble II SCU

来源:互联网 发布:淘宝推广拉人进群 编辑:程序博客网 时间:2024/05/21 22:37

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 0

Every 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 not

Obviously the side-length of the largest square is 2


Input

The 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≤1000

Output

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 0

Sample Output

1
2

#include<queue>#include<stack>#include<vector>#include<math.h>#include<cstdio>#include<numeric>//STL数值算法头文件#include<stdlib.h>#include<string.h>#include<iostream>#include<algorithm>#include<functional>//模板类头文件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<n; i++)            for(int j=0; j<m; j++)                scanf("%d",&a[i][j]);        int ans=0;        for(int i=1; i<n; i++)        {            for(int j=1; j<m; j++)            {                if(a[i][j]==1)                {                    dp[i][j]=min(dp[i][j-1],min(dp[i-1][j-1],dp[i-1][j]))+1;                }                ans=max(ans,dp[i][j]);            }        }        printf("%d\n",ans);    }}
0 0