首页 > 代码库 > [ACM] POJ 3740 Easy Finding (DFS)
[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.
Input
There are multiple cases ended by EOF. Test case up to 500.The first line of input is M, N (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; }
[ACM] POJ 3740 Easy Finding (DFS)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。