题目的意思就是在最少用几列,可以把所有行(代表一种状态区分开) 例如第一个样例,取每行前5个,全是不一样的,就能区分开了。
做法就是用二进制法,遍历子集。
AC代码:
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
const int N = 101;
int key[N];
int row ,col,m;
bool is;
void init() {
for (int i = 0; i < N ; i++ ) {
key[i] = 0;
}
}
/*void subset (int num) {
for (int i = 0; i < col ;i++) {
for (int j = 0 ; j < row ;j++) {
if(num & (1 << j))
res += pow(2,k++) * state[i][j];
}
if (vis[res] == 1) {
is = true;
return;
}
vis[res] = 1;
res = 0;
k = 0;
}
}*/
int num_of_1 (int num) {
int t = 0;
for (int i = 0 ; i < row ; i++) {
if (num & 1 << i)
t++;
}
return t;
}
bool subset(int num) {
for (int i = 0 ; i < col ; i++) {
for (int j = i + 1 ; j < col ;j++) {
if ((key[i] & num ) == (key[j] & num))
return false;
}
}
return true;
}
int main () {
int n ;
cin >> n;
while (n--) {
init();
int x;
cin >> row >> col;
for (int i = 0; i <col ; i++) {
for (int j = 0 ; j < row ; j++) {
cin >> x;
key[i] +=( 1 << (row - j - 1)) * x;
}
// cout <<i<<" "<< key[i]<<endl;
}
m = 18;
for (int i = 0 ; i < (1 << row) ; i++) {
int num = num_of_1(i);
if (num < m) {
if (subset(i))
m = num;
}
}
cout << m << endl;
}
return 0;
}