矩阵(01矩阵中找到k*k的全0子矩阵)

矩阵

Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 0    Accepted Submission(s): 0


 

Problem Description

有一个二维矩阵,长和宽分别是N,M。矩阵上的每个点有两个状态(0,1),问能不能找到一个K*K的子矩阵,子矩阵里面每个点的状态全为0?

 

 

Input

第一行为一个整数T,代表T组数据。(1=<T<=10)
第二行为三个整数N,M,K。(1<=N,M<=1000,1<=K<=min(N,M))
接下来N行,每行有M个整数,代表矩阵上对应的点的状态,状态只有0,1两种。

 

 

Output

对于每个测试样例,输出一行,如果能找到子矩阵,输出"Yes",否则输出"No"。每个测试样例占一行。

 

 

Sample Input

2

3 3 2

1 0 0

1 0 0

1 1 1

3 3 2

1 0 0

0 1 0

0 0 0

Sample Output

Yes 
No

 

题意就不说了

暴力应该是不行的,若果你枚举这个k*k的矩阵的左边端点,当k=n/2时候  时间复杂度是n^4次方  肯定超时

比赛的时候总觉得做过这样的问题,但是就是想不起来ヽ(*。>Д<)o゜

 

随后突然间来了灵感!!!!!!

如果矩阵的每一位置的值代表往下连续为0的个数,也是就是说每一行算是一个柱形图(向下的),那么只要在每一行找到

柱形图的长度>=k的连续的k个即可。

例子:

1 0 0

1 0 0

1 1 1

处理过后就是

0 2 2      第一个0代表往下有0个连续的0,第二个2代表往下有2个连续的0,第三个2代表往下有2个连续的0  

0 1 1      第一个0代表往下有0个连续的0,第二个1代表往下有2个连续的0,第三个1代表往下有2个连续的0

0 0 0      向上一下

每一行的值都可代表一个柱形图,其值就代表柱形图的高度,即连续为0个有多少个。

 

那这道题岂不是简单了O(∩_∩)O!!!!!!

 

输入的时候把这个矩阵处理一下成柱状图的形式,为了降低时间复杂度,我这里把这个柱形图的方向改为行,即第j列的第i个代表这一行左边来连续的0的个数,然后遍历每一列找出连续k个柱状高度>=k的矩阵即可!

 

 

 

代码:

/*
n^2的方法

按照列数在每一行搞出一个柱形图  代表下面最多有几个连续的0  最后枚举每列只要大于k的数连续出现k次即可
*/
#include<stdio.h>
#include<string>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<math.h>
using namespace std;
const int maxn=1010;
int matric[maxn][maxn];
int main()
{
    int t,n,m,k;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d %d %d",&n,&m,&k);//n行m列
        int cnt=0;
        for(int i=1; i<=n; i++)
        {
            cnt=0;
            for(int j=1; j<=m; ++j)
            {
                scanf("%d",&matric[i][j]);
                if(matric[i][j])//即使选连续0的个数
                    cnt=0;
                else
                {
                    cnt++;
                }
                matric[i][j]=cnt;
            }
        }//搞出柱形图
        int flag=1;
        for(int i=m; i>=k&&flag; --i) //枚举列数
        {
            cnt=0;
            for(int j=1; j<=n; ++j)//枚举行数
            {
                if(matric[j][i]>=k)
                    cnt++;
                else
                    cnt=0;
                if(cnt>=k)
                {
                    flag=0;
                    break;
                }
            }
        }
        if(flag)
            printf("No\n");
        else
            printf("Yes\n");
    }
}

 

posted @ 2018-11-03 20:35  _年少有为  阅读(1023)  评论(0编辑  收藏  举报