Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 16202 | Accepted: 4349 |
Description
Input
Output
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
给定由01构成的矩阵,问能不能选出几行构成新矩阵,使得新矩阵每列有且只有一个1.
枚举所有行,行号递增,判断每行是否可以选(是否与前面所选的行发生冲突),当前行可选时,第j列如果为1,则用vis[j]=1标记,当行号>n(行数)时,判断每列是否都有1.
#include <iostream> #include <stdio.h> #include <string.h> const int maxn=18; const int maxm=310; int mp[maxn][maxm]; bool vis[maxm]; int n,m; bool yes; using namespace std; bool row_ok(int rth)//rth为行号,判断第rth行可以选 { for(int j=1;j<=m;++j) if(vis[j]&&mp[rth][j])//第j列已经有1了 return false; for(int j=1;j<=m;++j)//可以选 if(mp[rth][j]) vis[j]=true; return true; } bool judge()//当选的行号大于n时,判断一下是不是每列都有1 { for(int j=1;j<=m;++j) if(!vis[j]) return false; return true; } void dfs(int rth) { if(rth>n+1)//因为当rth=n+1时,还需要判断judge() return; if(judge())//注意这两个if { yes=1; return; } for(int i=rth;i<=n&&!yes;++i) { if(row_ok(i)) { dfs(i+1);//注意这里不是dfs(step+1),选的行号是递增的 for(int j=1;j<=m;++j)//还原 if(mp[i][j]) vis[j]=0; } } } int main() { while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;++i) for(int j=1;j<=m;++j) scanf("%d",&mp[i][j]); memset(vis,0,sizeof(vis)); yes=0; dfs(1); if(yes) printf("Yes, I found it\n"); if(!yes) printf("It is impossible\n"); } return 0; }
[ACM] POJ 3740 Easy Finding (DFS)
原文:http://blog.csdn.net/sr_19930829/article/details/39758869