題目鏈接: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;
}