标签:
题目大意:给出一个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] && vis[j]) return false; return true; } bool manzu(){//判断是否每一列都有且仅有一个1 for (int j = 1; j <= n; j++) if (!vis[j]) return false; return true; } int dfs(int ans){ int i, j; if (ans > m+1)//注意遍历>m时还要判断manzu(),所以应该是超过m+1时才返回 return false; if (manzu()){//每一列都有且仅有一个1 flag = true; return true; } if (fuhe(ans)){//该行目前看来符合要求 for (j = 1; j <= n; j++) if (a[ans][j])//将该行有1的列全部都设为vis[j]=true; vis[j] = 1; for (j = ans; j <= m&&!flag; j++){//按行的先后dfs的,小于i行的之前已dfs if (dfs(j + 1))//接下来的全部ok,就可以返回true了 return true; } //遍历了ans+1到n之后都不行,则该行不行,告诉上一层,回溯 for (j = 1; j <= n; j++) if (a[ans][j])//回溯之前记住要还原 vis[j] = 0; return false; } } int main() { while (scanf("%d%d", &m, &n) != EOF){ int i, j; for (i = 1; i <= m; i++) for (j = 1; j <= n; j++) scanf("%d",&a[i][j]); memset(vis, 0, sizeof(vis)); flag = false; for (i = 1; i <= m; i++){ if (dfs(i)) break; } if (flag) printf("Yes, I found it\n"); else printf("It is impossible\n"); } return 0; }
题目链接:http://poj.org/problem?id=3740
poj 3740 -- Easy Finding (dfs)
标签:
原文地址:http://www.cnblogs.com/lxzd723/p/4397264.html