zoukankan      html  css  js  c++  java
  • 3280 easyfinding

    3280 easyfinding

     

     时间限制: 1 s
     空间限制: 128000 KB
     题目等级 : 钻石 Diamond
     
     
    题目描述 Description

     给一个M 行N  列的01 矩阵,让你选出一些行 (不一定选出全部行)使得每一列都有 
    且只有一个1。其中M<= 16,N<=300 。

    输入描述 Input Description

        输入含有多组数据。以文件结束符(eof )为结束。最多会有500 组。 
        输入之间会有梯度,也就是不是每组输入都是500 组。 
        对每组数据,第一行:两个由空格隔开的整数M 和N 。然后是M 行每行N  个等于0 
    或者等于1 的整数,整数之间由空格隔开。

    输出描述 Output Description

    对每组数据输出一行,如果可以达到题中要求,输出Yes 否则输出No  。均不包括引号。

    样例输入 Sample Input

    3 3 
    0 1 0 
    0 0 1 
    1 0 0 
    4 4 
    0 0 0 1 
    1 0 0 0 
    1 1 0 1 
    0 1 0 0

    样例输出 Sample Output

    Yes 
    No

    数据范围及提示 Data Size & Hint

    注意时间复杂度

    分类标签 Tags 点此展开 

     
    第一次没读明白题目,任选几行组成(不一定连续)
    用枚举做就AC了一个点
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    int map[17][301];
    int n,m;
    void dfs(){
        int flag=0;
        for(int i=1;i<=m;i++)
            for(int j=i;j<=m;j++){
                for(int k=1;k<=n;k++){
                    int num=map[j][k]-map[i-1][k];
                    if(num!=1) break;
                    if(k==m){flag=1;printf("Yes
    ");return ;}
                }
            }
        if(!flag) printf("No
    ");
    }
    int main(){
        while(scanf("%d%d",&m,&n)==2){
            memset(map,0,sizeof map);
            for(int i=1,x;i<=m;i++){
                for(int j=1;j<=n;j++){
                    scanf("%d",&x),map[i][j]=map[i-1][j]+x;
                }
            }
            dfs();
        }
        return 0;
    } 

    正解AC代码:

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    using namespace std;
    #define N 310
    struct node{
        int vis[N];
    }a[N];
    int n,m,head,tail,flag;
    int v[20][N];
    int ok(int x){//验证 
        for(int i=1;i<=m;i++)
            if(!a[x].vis[i])return 0;
        return 1;
    }
    void bfs(){
        while(head<=tail){//不明确第一个状态,so"<=" 
            if(head>10*n) return ;//防止死循环 
            for(int i=1;i<=n;i++){
                ++tail;
                for(int j=1;j<=m;j++)//回溯 
                    a[tail].vis[j]=a[head].vis[j];
                int ff=0;
                for(int j=1;j<=v[i][0];j++)
                    if(a[tail].vis[v[i][j]]){//有1 - 不满足 
                        ff=1;break;
                    }
                if(!ff){
                    for(int j=1;j<=v[i][0];j++)
                        a[tail].vis[v[i][j]]=1;//更新vis 
                    if(ok(tail)){
                        flag=1;
                        printf("Yes
    ");
                        return ;
                    }
                }
                else
                    tail--;//当前不满足,回溯 
            }
            head++;
        }
    }
    int main(){
        while(scanf("%d%d",&n,&m)==2){
            memset(a,0,sizeof a);
            memset(v,0,sizeof v);
            for(int i=1,x;i<=n;i++){
                for(int j=1;j<=m;j++){
                    scanf("%d",&x);
                    if(x) v[i][++v[i][0]]=j;//模拟动态数组,v[i][++v[i][0]]=j;记录第i行第v[i][0]个1的列号j 
                }
            }
            head=0;tail=0;flag=0;
            bfs();
            if(!flag) printf("No
    ");
        }
        return 0;
    }
  • 相关阅读:
    接口类和抽象类
    生成器和迭代器
    装饰器
    KMP算法(java,c++)
    java EE
    XML
    SQL语法
    单元测试
    JDBC
    SpringCloud
  • 原文地址:https://www.cnblogs.com/shenben/p/5582864.html
Copyright © 2011-2022 走看看