题意:
给出n个k维01向量,求一个k维01向量,使得它和给定的向量组的相同位数最大值最小。
题解:
基本思路:最大值最小->最小值最大->bfs搜最小值->取最大
汉明距离:d(x,y) = x与y不同的位的个数。
于是问题变成了求一个s,使得他到给定向量组的汉明距离最小值最大。
于是bfs求每个向量到给定向量组的汉明距离最小值。
取最大的一只。
本题告诉我们:
最大值最小不一定是二分,因为可以转化成最小值最大。
而最小值最大也不一定是二分,因为可以bfs
成功的缴了智商税………于是拿出小本本记下来,以加深印象。
本题做法很多,比如打牌,或者fwt之类。。(fwt是什么啊喂,我怎么这么弱
Code:
//
// Created by calabash_boy on 18-6-15.
//
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+100;
const int INF = 0x3f3f3f3f;
int dis[1<<21];
int n,k;
char s[21];
int que[1<<21],l,r;
int main(){
scanf("%d%d",&n,&k);
int N = 1<<k;
for (int i=0;i<N;i++)dis[i] = INF;
for (int i=0;i<n;i++){
scanf("%s",s);
int val =0;
for (int i=0;i<k;i++){
val+= (s[i]=='1')*(1<<i);
}
dis[val]=0;
}
for (int i=0;i<N;i++){
if(dis[i]==0){
que[r++] = i;
}
}
while (l<r){
int head = que[l++];
for (int i=0;i<k;i++){
int temp = head^(1<<i);
if(dis[temp]>dis[head]+1){
dis[temp] = dis[head]+1;
que[r++] = temp;
}
}
}
int ans =0;
for (int i=0;i<N;i++){
if(dis[i]>dis[ans]){
ans =i;
}
}
for (int i=0;i<k;i++){
if(ans&(1<<i))printf("1");
else printf("0");
}
return puts(""),0;
}