UVA-11205
题意:给出n个p位的2进制串,求最少保留多少位可以区分这些2进制串。
解题思路:枚举子集。1 -> 2^p 中的每个数字用二进制表示都是一种子集的获取方式。把2进制串转成10进制,用 & 运算的取保留下的值,判断是否都不一样,都不一样计算位数,取最小的一个。
/*************************************************************************
> File Name: UVA-11205.cpp
> Author: Narsh
>
> Created Time: 2016年07月22日 星期五 15时36分01秒
************************************************************************/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
int s[300];
bool pd[400000];
int n,m,k,l,t,tot;
bool flag;
int main() {
//freopen("xx.in","r",stdin);
scanf("%d",&t);
memset(pd,true,sizeof(pd));
while (t--) {
scanf("%d%d",&m,&n);
for (int i = 1; i <= n; i++){
l=0;
for (int j = 1; j <= m; j++){
scanf("%d",&k);
l=l*2+k;
}
s[i]=l;
}
tot=16;
for (int r = 0; r < (1<<m); r++) {
flag = true;
int temp;
for (int i = 1; i <= n; i++) {
temp = s[i] & r;
if (pd[temp]) pd[temp]=false;
else {
flag = false;
break;
}
}
if (flag) {
l = 0;
for (int i = 0; i < m; i++)
if ( r & 1 << i)
l++;
if (l < tot) tot = l;
}
for (int i = 1; i <= n; i++){
temp = s[i] & r;
pd[temp]=true;
}
}
printf("%d\n",tot);
}
}