zoukankan      html  css  js  c++  java
  • 矩阵(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
    ");
            else
                printf("Yes
    ");
        }
    }
    
  • 相关阅读:
    list转datatable,SqlBulkCopy将DataTable中的数据批量插入数据库
    Html.BeginForm 与Section、Partial View 和 Child Action
    e.stopPropagation();与 e.preventDefault();
    NPOI导出
    Excel导入导出(篇二)
    Excel导入导出,通过datatable转存(篇一)
    ajax请求加载Loading或错误提示
    jQuery UI dialog
    Zebra_Dialog 弹出层插件
    Google浏览器导出书签
  • 原文地址:https://www.cnblogs.com/dchnzlh/p/10427308.html
Copyright © 2011-2022 走看看