1、这是一道好题。通过这道题,我学会了用二进制法来枚举子集。刚开始,我是使用位向量法,打算通过回溯法来枚举子集,相当麻烦不说,还陷入了死循环。后来采用二进制法,枚举子集就像枚举整数一样简单!
2、要注意的就是变量的作用域,小心别搞错了。还有就是要查询一个数组里有没有两个相同的数的方法——不是O(n^2)枚举,而是先排序,再比较相邻的数。
3、方法正确后,一次AC~
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int p,n,end,a[105],c[105];
int main(){
//freopen("a.txt","r",stdin);
int T,min,x;
scanf("%d",&T);
while(T--){
scanf("%d%d",&p,&n);
for(int i=0;i<n;i++){
int sum=0,temp;
for(int j=p-1;j>=0;j--){
scanf("%d",&temp);
sum+=(temp<<j);
}
a[i]=sum;
}
min=p;
for(int i=0;i<(1<<p);i++){
int num=0;
for(int j=1;j<(1<<p);j<<=1)
if(i&j) num++;
memcpy(c,a,sizeof(a));
for(int k=0;k<n;k++)
c[k]=a[k]&i;
sort(c,c+n);
for(x=0;x<n-1;x++)
if(c[x]==c[x+1]) break;
if(x==n-1){
if(min>num)
min=num;
}
}
printf("%d\n",min);
}
return 0;
}