题目链接:https://codeforces.com/contest/1285/problem/D
题目大意:给n个数字,用一个X跟所有数字异或,使得到的数字的最大值最小
题目思路:太久没写题,水平掉太快了。。。这题我的想法是从高位开始,如果遇到全1或全0那么就是0,如果有的0有的1,那么就尝试这位不异或和异或1得到的结果,看看最大值哪个小就按照哪个来,但是感觉这样没考虑后面的,应该是错的,看了半天题解才看懂。。太菜了。。
其实整体思路都是对的,就只差最后一步。如果这一位既有1,又有0,那么答案中这一位一定是1,为啥呢。因为你想要最大值,如果这一位不异或,有1的出来顶,如果异或,那么这位是0的出来顶,总能把这一位顶出1。但是,右边咋取呢?这一位的1,究竟是因为异或了出来的,还是没异或出来的?这就有两种情况,需要递归。因为如果只有一位数字的话,结果是肯定的,所以先递归到最低位,然后用之后的答案不断更新高位,以此获得结果,感觉这题非常好。
以下是代码:
#include<bits/stdc++.h>
using namespace std;
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
const int MAXN = 1e5+5;
const int MOD = 1e9+7;
int a[MAXN];
int n;
vector<int>v;
int solve(vector<int>v,int pos){
if(pos<0)return 0;
vector<int>l,r;
int len=v.size();
rep(i,0,len-1){
if(((1<<pos)&v[i])==(1<<pos))l.push_back(v[i]);
else r.push_back(v[i]);
}
if(!l.size())return solve(r,pos-1);
if(!r.size())return solve(l,pos-1);
return min(solve(l,pos-1),solve(r,pos-1))+(1<<pos);
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
v.clear();
while(cin>>n){
rep(i,1,n)cin>>a[i],v.push_back(a[i]);
cout<<solve(v,30)<<endl;
}
return 0;
}