[ACM] POJ 3740 Easy Finding (DFS)

Easy Finding

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 16482   Accepted: 4476

Description

Given a M×N matrix AAij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn
contains and only contains one 1.

Input

There are multiple cases ended by EOF. Test case up to 500.The first line of input is MN (M ≤ 16, N ≤ 300).
The next M lines every line contains N integers separated by space.

Output

For each test case, if you could find it output "Yes, I found it", otherwise output "It is impossible" per line.

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, I found it
It is impossible

Source

POJ Monthly Contest - 2009.08.23, MasterLuo

解题思路:

题意为给出n*m的01矩阵,问能不能从中选出一些行,使得这些行组成的新矩阵中,每列有且只有一个1.

本题用Dlx可解,明显的完全覆盖问题。这里练习DFs,用DFS按照行号递增的顺序枚举行就可以.一开始犯了一个很严重的错误,就是没有按行号递增的顺序,导致了重复,其实 1 2 5和 5 1 2其实是一样的,所以DFS(int row), 参数是行号,下一层递归为DFs(row+1), 每次进入DFs都要首先判断是否符合题意,即新矩阵每列有且只有一个1,用vis[j]数组表示新矩阵中第j列是否已经有一个1,如果满足该条件,就不用往下继续递归了,直接标记成功,return即可。

通过这道题,加深了对递归的理解,感觉只要想明白,递归也不是那么难理解。

假设当n=4时,搜索的行号是按这样的顺序:

1

1 2

1 2 3

1 2 3 4

1 2 4

1 3

1 3 4

1 4

2

2 3

2 3 4

2 4

3

3 4

4

代码:

#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <stdlib.h>
#include <cmath>
#include <iomanip>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cctype>
using namespace std;
#define ll long long
const int maxn=18;
const int maxm=302;
int mp[maxn][maxm];
int n,m;
bool vis[maxm];// vis[i]表示第i列是否有一个1了
bool ok;
int hash[maxn];//第i行有多少个1

bool yes(int row)//判断第row行可不可行
{
    for(int i=1;i<=m;i++)
        if(mp[row][i]&&vis[i])
        return false;
    return true;
}

void DFS(int cnt,int row)//参数cnt为当前所选的行里面列已经有多少个1,row是当前选择的第几行
{
    if(cnt==m||(row>n&&cnt==m))///这里也要注意,当选择的行号大于n时,也要判断已选择的行号是否满足题意
    {
        ok=1;
        return;
    }
    if(row>n)
        return;
    for(int i=row;i<=n;i++)///所犯的一个很严重的错误,一开始写成i=1了,重复了,行号是按照递增的顺序来选择的,1 5 8和5 1 8是同一种情况
    {
        if(yes(i))
        {
            for(int j=1;j<=m;j++)
            {
                if(mp[i][j])
                    vis[j]=1;
            }
            DFS(cnt+hash[i],i+1);
            if(ok)
                break;
            for(int j=1;j<=m;j++)
            {
                if(mp[i][j])
                    vis[j]=0;
            }
        }
    }
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(hash,0,sizeof(hash));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
        {
            scanf("%d",&mp[i][j]);
            if(mp[i][j])
                hash[i]++;
        }
        ok=0;
        memset(vis,0,sizeof(vis));
        DFS(0,1);
        if(ok)
            printf("Yes, I found it\n");
        else
            printf("It is impossible\n");

    }
    return 0;
}
时间: 2024-10-12 20:49:21

[ACM] POJ 3740 Easy Finding (DFS)的相关文章

POJ 3740 Easy Finding(dfs回溯)

B - Easy Finding Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Practice POJ 3740 Description Given a M× N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn

[ACM] POJ 3740 Easy Finding (DLX模板题)

Easy Finding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16178   Accepted: 4343 Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn contains and only contains one 1.

[ACM] POJ 3740 Easy Finding (DFS)

Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16202   Accepted: 4349 Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn contains and only contains one 1. Input There a

poj 3740 -- Easy Finding (dfs)

题目大意:给出一个m行n列的数组,元素只有0和1, 问:能不能找出几行,使得每一列都有且仅有一个1. 分析:直接深搜即可 #include<iostream> #include<cstdio> using namespace std; int vis[311];//记录该列有1没 int n, m; int a[20][311]; bool flag; bool fuhe(int i){ for (int j = 1; j <= n; j++) if (a[i][j] &am

poj 3740 Easy Finding(Dancing Links)

Easy Finding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 15668   Accepted: 4163 Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn contains and only contains one 1.

POJ 3740 Easy Finding

题目链接:http://poj.org/problem?id=3740 dancing links 入门题 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <string> 5 #include <iomanip> 6 using namespace std; 7 int M, N; 8 #define maxn 16*300+5 9 int R[

POJ 3740 Easy Finding DLX

题意:给你一个0,1矩阵 ,求精确覆盖 解题思路: DLX 解题代码: 1 // File Name: poj3740.cpp 2 // Author: darkdream 3 // Created Time: 2014年10月04日 星期六 20时06分31秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #i

[ACM] poj 1088 滑雪 (记忆化搜索DFS)

求n*m网格内矩形的数目[ACM] poj 1088 滑雪 (记忆化搜索DFS),布布扣,bubuko.com

(水 dfs) poj 3740

Easy Finding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16854   Accepted: 4567 Description Given a M×N matrix A. Aij ∈ {0, 1} (0 ≤ i < M, 0 ≤ j < N), could you find some rows that let every cloumn contains and only contains one 1.