题目描述 Description
给一个M 行N 列的01 矩阵,让你选出一些行 (不一定选出全部行)使得每一列都有
且只有一个1。其中M<= 16,N<=300 。
输入描述 Input Description
输入含有多组数据。以文件结束符(eof )为结束。最多会有500 组。
输入之间会有梯度,也就是不是每组输入都是500 组。
对每组数据,第一行:两个由空格隔开的整数M 和N 。然后是M 行每行N 个等于0
或者等于1 的整数,整数之间由空格隔开。
输出描述 Output Description
对每组数据输出一行,如果可以达到题中要求,输出Yes 否则输出No 。均不包括引号。
样例输入 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
分类标签 Tags 点此展开
第一次没读明白题目,任选几行组成(不一定连续)
用枚举做就AC了一个点
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define N 310
struct node{
int vis[N];
}a[N];
int n,m,head,tail,flag;
int v[20][N];
int ok(int x){//验证
for(int i=1;i<=m;i++)
if(!a[x].vis[i])return 0;
return 1;
}
void bfs(){
while(head<=tail){//不明确第一个状态,so"<="
if(head>10*n) return ;//防止死循环
for(int i=1;i<=n;i++){
++tail;
for(int j=1;j<=m;j++)//回溯
a[tail].vis[j]=a[head].vis[j];
int ff=0;
for(int j=1;j<=v[i][0];j++)
if(a[tail].vis[v[i][j]]){//有1 - 不满足
ff=1;break;
}
if(!ff){
for(int j=1;j<=v[i][0];j++)
a[tail].vis[v[i][j]]=1;//更新vis
if(ok(tail)){
flag=1;
printf("Yes
");
return ;
}
}
else
tail--;//当前不满足,回溯
}
head++;
}
}
int main(){
while(scanf("%d%d",&n,&m)==2){
memset(a,0,sizeof a);
memset(v,0,sizeof v);
for(int i=1,x;i<=n;i++){
for(int j=1;j<=m;j++){
scanf("%d",&x);
if(x) v[i][++v[i][0]]=j;//模拟动态数组,v[i][++v[i][0]]=j;记录第i行第v[i][0]个1的列号j
}
}
head=0;tail=0;flag=0;
bfs();
if(!flag) printf("No
");
}
return 0;
}