/*刚开始题目没怎么看懂,以为就是将给的n组数据中同时将每一列全部变成0,如果没有重复的,说明此列可去掉。后来发现这样想是不对的,会存在很多错误。仔细读题才发现,这道题的意思是找到一个n位的二进制数i,让它与n组给定的数据进行&操作,如果操作完后n组数据任不同,则i是可取的,但是我们要取的是n为数字中1的数目最少的i。*/
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include"iostream" 2 #include"stdio.h" 3 #include"string.h" 4 #include"cmath" 5 using namespace std; 6 #define mx 105 7 int a[mx][20]; 8 int b[mx]; 9 int c[mx]; 10 int p,n; 11 int judge(int c[]) 12 { 13 int i,j; 14 for(i=0;i<n;i++) 15 for(j=i+1;j<n;j++) 16 { 17 if(c[i]==c[j]) return 0; 18 } 19 return 1; 20 } 21 int main() 22 { 23 int t; 24 cin>>t; 25 while(t--) 26 { 27 cin>>p>>n; 28 int i,j; 29 for(i=0;i<n;i++) 30 for(j=0;j<p;j++) 31 cin>>a[i][j]; 32 memset(b,0,sizeof(b)); 33 for(i=0;i<n;i++) 34 { 35 for(j=0;j<p;j++) 36 b[i]+=(a[i][j]<<(p-j-1)); 37 } 38 int mi=20; 39 for(i=1;i<(1<<p);i++) 40 { 41 for(j=0;j<n;j++) 42 { 43 c[j]=(b[j]&i); 44 } 45 int count1=0; 46 if(judge(c)) 47 { 48 for(j=0;j<p;j++) 49 { 50 if((i>>j)&1) count1++; 51 } 52 if(count1<mi) mi=count1; 53 } 54 } 55 cout<<mi<<endl; 56 } 57 }