当前位置: 代码迷 >> 综合 >> Educational Codeforces Round 76 (Rated for Div. 2) F (meet-in-the-middle)
  详细解决方案

Educational Codeforces Round 76 (Rated for Div. 2) F (meet-in-the-middle)

热度:66   发布时间:2024-02-10 01:08:01.0

https://codeforces.com/contest/1257/problem/F
在这里插入图片描述

思路

首先如果暴力做的话, 就是 100*2^30, 肯定 T。
考虑 meet in the mid , 将 30 位的数拆分成前 15 位和后 15 位。
然后暴力枚举 x 异或数组 a 的所有状态, 用 map 存起来, 然后考虑前 15 位和后 15 位组合起来能否满足要求。 (比如前 15 位中 a1 比 a2 多修改了一个 1, 那么在后 15 位中需要找到a2 比 a1 多修改一个 1 的进行组合)

代码

#include<bits/stdc++.h>
#define ios std::ios::sync_with_stdio(false)
#define rep(i,a,n) for (int i=a;i<=n;i++)
#define per(i,n,a) for (int i=n;i>=a;i--)
#define pb push_back
using namespace std;
const int N = 2e5 + 10, MOD = 1e9+7, inf = 0x3f3f3f3f;
int a[N];
map<vector<int>, int> mp;
int gao(int x){int res = 0;while(x){res += x & 1;x >>= 1;}return res;
}
signed main()
{ios;int n;cin >> n;rep(i,1,n){cin >> a[i];}vector<int> vec,tmp;rep(i,0,(1 << 15)-1){vec.clear();rep(j,1,n){vec.pb(gao(a[j]%(1<<15) ^ i));}mp[vec] = i;}rep(i,0,(1<<15)-1){vec.clear();rep(j,1,n){vec.pb(gao((a[j]>>15) ^ i));}rep(j,0,15){tmp.clear();rep(k,0,n-1){tmp.pb(j - vec[k]);}if (mp.count(tmp)){int x = mp[tmp];cout << (i << 15 | x) << '\n';return 0;}}}cout << -1 << '\n';return 0;
}
  相关解决方案