hdu 5536 Chip Factory (字典树)

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=5536

题意

给定一个数列,从数列中取出坐标不同的三个数,其中两个求和,再和另外一个数异或,求异或值的最大值。

思路

hdu4825相似,只不过因为要三个坐标不同,如果直接去字典树上匹配的话不能判断坐标,所以再匹配之前先将s[i]和s[j]删除,匹配完之后再添加上。

代码

#define push_back pb
#define make_pair mk
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<cmath>
#include<map>
#include<algorithm>
#include<string>
#include<string.h>
#include<set>
#include<queue>
#include<stack>
#include<functional>
using std::pair;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>PII;
const double PI=acos(-1);
const int maxn = 1e3 + 10;
const int maxm = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod =1e9+7;
const ll inf =1e18;
using namespace std;
int n;
struct Trie
{
    int son[maxn*30][2],cnt,sum[maxn*30],end[maxn*30];

    void init()
    {
        memset(son,0,sizeof(son));
        cnt=0;
        memset(sum,0,sizeof(sum));
        memset(end,0,sizeof(end));
    }

    void insert(int n)
    {
        int rt=0;
        for(int i=31;i>=0;i--)
        {
            int t=(n>>i)&1;
            if(son[rt][t]==0) son[rt][t]=++cnt;
            rt=son[rt][t];
            sum[rt]++;
        }
        end[rt]=1;
    }
    void del(int n)
    {
        int rt=0;
        for(int i=31;i>=0;i--)
        {
            int t=(n>>i)&1;
            rt=son[rt][t];
            sum[rt]--;
        }
    }

    int query(int n)
    {
        int rt=0;
        int ans=0;
        for(int i=31;i>=0;i--)
        {
            int t=((n>>i)&1)^1;
            if(son[rt][t]==0||sum[son[rt][t]]==0) t^=1;
            ans|=(t<<i);
            rt=son[rt][t];
        }
        return ans;
    }
}trie;

int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        trie.init();
        scanf("%d",&n);
        int a[1010];
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
            trie.insert(a[i]);
        }
        int ans=0;
        for(int i=0;i<n-1;i++)
        {
            for(int j=i+1;j<n;j++)
            {
                trie.del(a[i]);
                trie.del(a[j]);
                int res=trie.query(a[i]+a[j]);
                res^=(a[i]+a[j]);
                ans=max(ans,res);
                trie.insert(a[i]);
                trie.insert(a[j]);
            }
        }
        printf("%d\n",ans);
    }
}

当然这个题因为9s的时限,用暴力也不会超时,时间为4s,而字典树为3.8s,字典树对这个题并没有太大的优势。

#define push_back pb
#define make_pair mk
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include<cmath>
#include<map>
#include<algorithm>
#include<string>
#include<string.h>
#include<set>
#include<queue>
#include<stack>
#include<functional>
using std::pair;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>PII;
const double PI=acos(-1);
const int maxn = 1e3 + 10;
const int maxm = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int mod =1e9+7;
const ll inf =1e18;
using namespace std;
int n;
int a[1010];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        int res=0;
        for(int i=0;i<n-2;i++)
        {
            for(int j=i+1;j<n-1;j++)
            {
                for(int k=j+1;k<n;k++)
                {
                    res=max(res,(a[i]+a[j])^a[k]);
                    res=max(res,(a[i]+a[k])^a[j]);
                    res=max(res,(a[k]+a[j])^a[i]);
                }
            }
        }
        printf("%d\n",res);
    }
}

猜你喜欢

转载自blog.csdn.net/a670531899/article/details/81710443
今日推荐