Chip Factory HDU - 5536

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Chip Factory HDU - 5536相关的知识,希望对你有一定的参考价值。

Chip Factory HDU - 5536

题意:

给你n个数,让你从中选出i,j,k三个下标,求最大的 (a[i]+a[j])^ a[k]

题解:

这种查找最大异或一般有两个方向,一个是有公式推导规律可循,另一个可以联合01字典树。
如何用01字典树做呢?
我们先将所有所有数插入到字典树中,然后暴力枚举i和j,求出a[i]+a[j]的和sum,现在我们要求a[k],让sum和a[k]的值最大,我们可以将sum取反,然后在字典树上找最接近sum的值,那就是符合的k,当然在查找前要先删除i和j,因为i,j,k三者不能重复,查找完再加回去

好吧,这个题给了9s,直接暴力也能做!!

代码:

字典树

#include<bits/stdc++.h>
#define debug(a,b) printf("%s = %d\\n",a,b);
typedef long long ll;
using namespace std;

inline int read(){
   int s=0,w=1;
   char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
   while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
   return s*w;
}
const int maxn=1e3+8;
int a[maxn],num[maxn];
int rtnum;
int root;
struct node{
	int cnt;
	int nxt[4];
	void init(){
		cnt=0;
		nxt[0]=nxt[1]=-1;
	}
}T[maxn*200];
void insert(int x){
	int now=0;
	for(int i=0;i<32;i++){
		a[i]=x&1;
		x>>=1;
	}
	for(int i=31;i>=0;i--){
		int x=a[i];
		if(T[now].nxt[x]==-1){
			T[rtnum].init();//开新点
			T[now].nxt[x]=rtnum++; //新点的编号 
		}
		now = T [now].nxt[x];
		T[now].cnt++;//这个点出现一次 
	}
}
ll search(int x){
	int now=0;
	ll ans =0;
	for(int i=0;i<=31;i++){
		a[i]=(x&1);
		x>>=1;
	}
	for(int i=31;i>=0;i--){
		int x=a[i];
		if(T[now].nxt[1-x]==-1||T[T[now].nxt[1-x]].cnt<=0){
			/*
			如果1-x无路可走,只能走x的路 
			*/ 
			now = T[now].nxt[x]; 
		}
		else 
		{
			ans+=1ll<<i;
			now=T[now].nxt[1-x];
		}
	}
	return ans;
}
void Trie_dele(int x){
	int now=0;
	for(int i=0;i<=31;i++){
		a[i]=x&1;
		x>>=1; 
	}
	for(int i=31;i>=0;i--){
		int tmp=a[i];
		now = T[now].nxt[tmp];
		T[now].cnt--;
	}
}
int main()
{
	int t;
	t=read();
	while(t--){
		int n;
		ll ans=-1;
		rtnum=1;
		n=read();
		T[0].init();
		for(int i=1;i<=n;i++){
			num[i]=read();
			insert(num[i]);
		}
		for(int i=1;i<=n;i++){
			Trie_dele(num[i]);
			for(int j=1;j<=n;j++){
				if(i==j)continue;
				
				Trie_dele(num[j]);
				ans=max(ans,search(num[i]+num[j]));
				insert(num[j]);
			}
			insert(num[i]);
		}
		printf("%lld\\n",ans);
	}
	return 0;
}

暴力

#include <set>
#include <map>
#include <deque>
#include <ctime>
#include <stack>
#include <cmath>
#include <queue>
#include <string>
#include <cstdio>
#include <vector>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

typedef long long LL;
typedef pair<LL, LL> pll;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef unsigned long long uLL;

#define lson rt<<1
#define rson rt<<1|1
#define name2str(name)(#name)
#define bug printf("**********\\n");
#define IO ios::sync_with_stdio(false);
#define debug(x) cout<<#x<<"=["<<x<<"]"<<endl;
#define FIN freopen("/home/dillonh/CLionProjects/in.txt","r",stdin);

const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1000 + 7;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const LL INF = 0x3f3f3f3f3f3f3f3fLL;

int t, n;
int s[1007];

int main() {
#ifndef ONLINE_JUDGE
    FIN;
#endif
    scanf("%d", &t);
    while(t--) {
        scanf("%d", &n);
        LL ans = -1;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &s[i]);
        }
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j < i; j++) {
                for(int k = 1; k < j; k++) {
                    ans = max(ans, (LL)(s[i] + s[j]) ^ s[k]);
                    ans = max(ans, (LL)(s[i] + s[k]) ^ s[j]);
                    ans = max(ans, (LL)(s[j] + s[k]) ^ s[i]);
                }
            }
        }
        printf("%lld\\n", ans);
    }
    return 0;
}

以上是关于Chip Factory HDU - 5536的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5536 Chip Factory

HDU 5536--Chip Factory(暴力)

HDU 5536 Chip Factory

HDU5536 Chip Factory

HDU - 5536 Chip Factory 字典树的删除

hdu 5536 Chip Factory 字典树+bitset 铜牌题