3つのアレイ(hdu 6625)

タイトルリンク

ボーイフレンド自動質問機の最初の質問

オリジナルのアイデア:

  もともとはバイナリのa配列から辞書ツリーを作成し、最適なマッチングのためにb配列を使用したかったのですが、繰り返しの問題への対処方法が思いつきませんでした。

後で:

  kan、wan、およびtiをしばらくすると、私はこれを見つけました。

    バイナリに従って2つの配列に対して2つの辞書ツリーaとbをそれぞれ構築し、各検索に対して最適なマッチングを実行します。

  コードを詳しく見る

#include <bits / stdc ++。h>
 using  namespace std;
 const  int maxn = 3e6 + 10 ;
 #define ios std :: ios :: sync_with_stdio (false)
 struct node 
{ 
    int ci、di [ 2 ]; /// cは現在のポイントが使用される回数di 

は、現在のビットが0と1である添え字を格納します}; ノードtreea [maxn]、treeb [maxn]; /// 2つのツリー
int cnta、cntb; /// 2つのツリー
void init()の最大添え字()/// 初期化
{
     forint i = 0 ; i <= cnta; i ++ ){ 
        treea [i] .ci= 0 ; 
        treea [i] .di [ 0 ] = treea [i] .di [ 1 ] = 0 ; 
    } 
    forint i = 0 ; i <= cntb; i ++ ){ 
        treeb [i] .ci = 0 ; 
        treeb [i] .di [ 0 ] = treeb [i] .di [ 1 ] = 0 ; 
    } 
} 
void insert1(int a)
{ 
    int dir = 1 ; /// 初始坐标
    forint i = 32 ; i> =0 ; i- ){
         int t =(a >> i&1 );
         if(treea [dir] .di [t] == 0){ /// 現在のビットがtの場合、 
            treea [ dir] .di [t] = ++ cnta; 
        } 
        dir = treea [dir] .di [t]; /// この座標に変更 
        treea [dir] .ci ++; /// 使用度+ 1 
    } 
} 
void insert2(int b)/// Ibid。
{
     int dir = 1 ;
     forint i = 32 ; i> = 0; i- ){
         int t =(b >> i&1 );
        if(treeb [dir] .di [t] == 0 ){ 
            treeb [dir] .di [t] = ++ cntb; 
        } 
        dir = treeb [dir] .di [t]; 
        treeb [dir] .ci ++ ; 
    } 
} 
int get_ans()
{ 
    int ca = 1、cb = 1 ; /// 两个初始坐标
    int ans = 0 ;
    forint i = 32 ; i> = 0 ; i --){
        int zeroa = 0 , zerob = 0 , onea = 0 , oneb = 0 ;///当前为01是否有使用度
        if(treea[ca].di[0] != 0 && treea[treea[ca].di[0]].ci > 0)zeroa = 1;
        if(treea[ca].di[1] != 0 && treea[treea[ca].di[1]].ci > 0)onea = 1;
        if(treeb[cb].di[0] != 0 && treeb[treeb[cb].di[0 ]]。ci> 0)zerob = 1 ;
        if(treeb [cb] .di [ 1 ]!= 0 && treeb [treeb [cb] .di [ 1 ]]。ci> 0)oneb = 1 ;
        if(onea && oneb){ 
            ca = treea [ca] .di [ 1 ]; 
            cb = treeb [cb] .di [ 1 ]; 
        } 
        else  if(zeroa && zerob){ 
            ca = treea [ca] .di [ 0 ]; 
            cb = treeb [cb] .di [ 0 ]; 
        }
        else  if(zeroa && oneb){ 
            ca = treea [ca] .di [ 0 ]; 
            cb = treeb [cb] .di [ 1 ]; 
            ans + =(1 << i); 
        } 
        else  if(zerob && onea){ 
            ca = treea [ca] .di [ 1 ]; 
            cb = treeb [cb] .di [ 0 ]; 
            ans + =(1 << i); 
        } 
        treea [CA] .ci - 
        treeb [CB] .ci -  
    }
    ansを
返します。
} int a [maxn]、b [maxn]、c [maxn]; 
署名されたmain()
{ 
    ios; 
    cin.tie(0); ///
     int t; 
    cin >> t;
    while(t- 
    { 
        int n; 
        cin >> n; 
        cnta = 1 ; 
        cntb = 1 ;
        forint i = 1 ; i <= n; i ++)cin >> a [i]、insert1(a [i]);
        forinti = 1 ; i <= n; i ++)cin >> b [i]、insert2(b [i]);
        forint i = 1 ; i <= n; i ++ ){ 
            c [i] = get_ans(); 
        } 
        sort(c + 1、c + 1 + n);
        forint i = 1 ; i <= n; i ++ ){ 
            cout << c [i];
            if(i!= n)cout << '  ' ; 
        } 
        cout << ' \ n'; 
        初期化(); 
    } 
    0を返し ます
}
コードを表示

 

おすすめ

転載: www.cnblogs.com/GoodVv/p/12729659.html