POJ 3740

http://poj.org/problem?id=3740

这是一道搜索+回溯的题目,也是我第一次接触到回溯。

题意就是找一些行,这些行可以使每一列都只存在一个1。

深搜加回溯:

memory:118K c++ runtime:674ms。#include <stdio.h>
#include <string.h>
#include <iostream>

using namespace std;

int a[20][305],n,m;
bool used[310],fin;

bool judge()            //判断是否已经寻找到那些行加起来可以使所有的列只存在一个1。
{
    for(int i=1;i<=m;i++)
        if(!used[i]) return false;
    return true;
}
bool check(int row)    //判断当前行是否有与之前行在某一列有冲突(都有1)
{
    for(int i=1;i<=m;i++)
        if(used[i]&&a[row][i]) return false; // 如果都有1的话,回溯。
    for(int i=1;i<=m;i++)
        if(a[row][i]) used[i]=true;   //如果不冲突的话,则把这一行用上,并把其的所有的1所在的行都标记上。
    return true;
}

void dfs(int s)
{
    if(fin||s>n+1) return;    //判断退出的标志,即输出的结果,或者行数已经超过了n+1。
    if(judge()) {
        printf("Yes, I found it\n");
        fin=true;
        return;
    }
    for(int i=s;i<=n&&!fin;i++)
    {
    if(check(i)){
        dfs(i+1);    
        for(int j=1;j<=m;j++)   //这就是回溯,因为如果I+1与之前的有冲突的话,if(check(i+1))则为false。所以执行的就应该是这一行。
            if(a[i][j]) used[j]=false;
        }
    }
}
int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                scanf("%d",&a[i][j]);
        fin=false;
        memset(used,false,sizeof(used));
        dfs(1);
        if(!fin) printf("It is impossible\n");
    }
    return 0;
}
时间: 2024-08-24 05:12:45

POJ 3740的相关文章

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(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

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 (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

[题目链接] http://poj.org/problem?id=3740 [算法] Dancing Links算法解精确覆盖问题 详见这篇文章 : https://www.cnblogs.com/grenet/p/3145800.html [代码] #include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale> #incl

[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

[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)

Easy Finding Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16482   Accepted: 4476 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 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