题目
题意
给数组 a [ ] a[] a[](长度为100),求是否存在 x x x, x ∈ [ 0 , 2 30 − 1 ] x∈[0,2^{30}-1] x∈[0,230−1],使得 a [ ] x o r x a[]\ xor\ x a[] xor x后, a [ ] a[] a[]的每一个元素的二进制上1的个数相同。
思路
meet-in-the-middle:左右分别枚举,左右匹配。
对于这题,枚举前15位,后15位,然后进行匹配。复杂度从
O
(
2
30
)
降
为
O
(
2
15
∗
l
o
g
(
2
15
)
)
O(2^{30})降为O(2^{15}*log(2^{15}))
O(230)降为O(215∗log(215))
#include <bits/stdc++.h>
using namespace std;
map<vector<int>,int>m1,m2;
int a[105],b[105];
int main(){
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=0;i<(1<<15);i++){
vector<int>v,cf;
for(int j=1;j<=n;j++){
int c=0;b[j]=a[j]^i;
for(int k=1;k<=15;k++){
c=c+(( b[j]&(1<<(k-1)) )>0);
}
v.push_back(c);
}
for(int j=2;j<=n;j++) cf.push_back(v[j-1]-v[j-2]);
if(m1.find(cf)==m1.end())m1[cf]=i;
}
for(int ti=0;ti<(1<<15);ti++){
int i=ti<<15; vector<int>v,cf;
for(int j=1;j<=n;j++){
int c=0;b[j]=a[j]^i;
for(int k=16;k<=30;k++){
c=c+(( b[j]&(1<<(k-1)) )>0);
}
v.push_back(c);
}
for(int j=2;j<=n;j++) cf.push_back(v[j-1]-v[j-2]);
if(m2.find(cf)==m2.end())m2[cf]=ti;
}
for(map<vector<int>,int> ::iterator it=m1.begin();it!=m1.end();it++){
vector<int>now=it->first,need;
for(int i=0;i<(int)now.size();i++){
// cout<<now[i]<<endl;
need.push_back(-now[i]);
}
map<vector<int>,int> ::iterator ii=m2.find(need);
if(ii!=m2.end()) {
cout<<it->second+( (ii->second)<<15)<<'\n';
return 0;
}
}
puts("-1");
return 0;
}