COJ 1216 異或最大值


      這道題也是擱了很久了,這次百度之星初賽中有道題感覺很相似,還是不會……,中午看status時,看到有個牛過了這道題,於是搜了搜,發現都是說用01二叉樹來解決的,我沒細看他們的方法,自己研究了一下,最后AC了,因為將一個 char 當成 8 位來用,所以空間是很小的;

     我的思路可能不太一樣,還有些暴力的痕跡,不過因為使用了位運算,加速比較明顯:二叉樹用數組來做,輸入一個數時,順帶將這個數在二叉樹中所經歷路徑用 1 來標記,然后遍歷這些數一遍,對每個數,找出二叉樹中已經標記的與這個數距離最遠的葉結點,相當於對每個數在其他數中找到和它異或最大的那個,然后把這個異或的結果來更新 ans ,就可以找到最大的了。

# include <stdio.h>
# include <string.h>

# define R 0x7
# define S 0x3
# define N 17

char tree[0x1<<(N-2)];
int a[100005];

void set_bit(int x)
{
    tree[x>>S] |= 0x1<<(x & R);
}

void clr_bit(int x)          /* 這個函數實際上沒用到,因為初始化是用memset()做的 */
{
    tree[x>>S] |= ~(0x1<<(x & R));
}

char get_bit(int x)
{
    return (char)((tree[x>>S]>>(x & R)) & 0x1);
}

int xor_max(int x)
{
    int i, k;
    
    k = 1;
    for (i = N-1; i >= 0; --i)
    {
        k <<= 1;
        if ((x>>i) & 0x1)
        {
            if (!get_bit(k)) k |= 0x1;
        }
        else
        {
            k |= 0x1;
            if (!get_bit(k)) k &= (~0x1);
        }
    }
    k -= (0x1<<N);
    
    return (k ^ x);
}

void pre_process(int x)
{
    int i;
    
    x += (0x1<<N);
    for (i = 0; i < N; ++i)
    {
        set_bit((x>>i));
    }
}

int max(int x, int y)
{
    return x>y? x:y;
}

int main()
{
    int n, i, ans;
        
    while (~scanf("%d", &n))
    {
        memset(tree, 0, sizeof(tree));    /* 這里應該相對耗時較多,本來想通過初始化節點1和2,最后發現不行,WA */
        
        for (i = 0; i < n; ++i)
        {
            scanf("%d", &a[i]);
            pre_process(a[i]);
        }
        
        ans = 0;
        for (i = 0; i < n; ++i)
        {
            ans = max(ans, xor_max(a[i]));
        }
        
        printf("%d\n", ans);
    }

    return 0;
}

.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM