利用移位操作来建立二进制数所对应的整数,对于读取字符串的时候所出现的‘*’要进行特殊处理。然后将可以因一位数字不同的二进制数所对应的整数建立对应关系,然后就使用匈牙利算法求出最终于的结果,同时注意该题有一个小坑,不要使用set集合类,否则会超时,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
#include<functional>
using namespace std;
int area[2100][2100];
class Solve{
public:
int N, M;
int S[2100];
int match[2100];
bool visit[2100];
int total;
void Init(){
total = 0;
memset(S, 0, sizeof(S));
memset(area,0,sizeof(area));
for (int i = 0; i < M; i++){
string s;
cin >> s;
int temp = 0;
int ind = -1;
for (int j = 0; j < N; j++){
if (s[j] == '*') ind = j;
if(s[j]=='1'){
temp |= (1 << (N-j-1));
}
}
S[temp]=1;
if (ind != -1){
temp |= (1 << (N-ind-1));
S[temp]=1;
}
}
for (int d1 = 0; d1 < 2100;d1++){
if (S[d1]){
total++;
for (int j = 0; j < N; j++){
int d2 = d1 ^ (1 << j);
if (S[d2]){
area[d1][d2] = 1;
}
}
}
}
}
bool Dfs(int d){
for (int d2 = 0; d2 < 2100;d2++){
if (area[d][d2] && !visit[d2]){
visit[d2] = true;
if (match[d2] == -1 || Dfs(match[d2])){
match[d2] = d;
return true;
}
}
}
return false;
}
void Deal(){
Init();
int ans = 0;
memset(match, -1, sizeof(match));
for (int d = 0; d < 2100;d++){
if (S[d]){
memset(visit, 0, sizeof(visit));
if (Dfs(d)) ans++;
}
}
cout << total - ans / 2 << endl;
}
};
int main(){
Solve a;
string s;
while (cin>>a.N>>a.M&&(a.N+a.M)){
a.Deal();
}
return 0;
}