天天看點

D. Ehab the Xorcist(構造+思維)

D. Ehab the Xorcist(構造+思維)
D. Ehab the Xorcist(構造+思維)

題意:給你u,v,要你構造一個最短的數組使得數組的各元素異或和為u,總和為v。

思路:

首先考慮幾組特殊的情況

u == v == 0傳回0即可

u == v != 0 傳回u即可

u > v 傳回 -1

這都比較簡單驗證

但凡要構造什麼東西的題目都是比較難的。這道題我們可以從異或這個運算出發,有一個很重要的性質就是 a ^ a = 0。這個性質告訴我們為了滿足異或和等于u,我們總是可以構造這樣的數組出來[a,a,u],這樣就滿足了異或和等于u。為了滿足和為v。因為數組中有了一個u我們還需要(v-u) / 2 = a就可以構造出來了。

也就是傳回的數組最長不會超過3,但是我們還需要考慮一下長度為2的數組。也就是說[a,a+u]這樣的情況,容易驗證a+u能合并當且僅當a & u = 0。這個自己可以去驗證一下,例如 5 9 的答案是[2,7]而不是[2,2,5](從二進制合并的角度去考慮),5 13的答案就是[4,4,5]。

注意a = (v - u)/ 2 如果不能整除也是不可行解傳回-1.

代碼:

#include<bits/stdc++.h>
using namespace std;

typedef long long int ll;
int main(){
    ll u ,v;cin>>u>>v;
    if(u > v){
        cout<<"-1"<<endl;return 0;
    }
    if(u == v && u != 0){
        cout<<"1"<<endl;
        cout<<u<<endl;
        return 0;
    }
    if(u == v && u == 0){
        cout<<"0"<<endl;return 0;
    }
    if((v-u)%2 == 1){
        cout<<"-1"<<endl;
        return 0;
    }
    ll x = (v - u)/2;
    ll y = (u + v)/2;
    if((x & u) == 0){
        cout<<"2"<<endl;
        cout<<x<<" "<<y<<endl;
        return 0;
    }
    cout<<"3"<<endl;
    cout<<x<<" "<<x<<" "<<u<<endl;
}
           

繼續閱讀