您的位置:首页 > 其它

hdu5536 Chip Factory (异或最大值)

2017-10-02 02:28 501 查看

题目:

给 n 个数,从中选出si, sj, sk使得(si+sj)⊕sk最大,输出最大值。n≤1000,si≤109

分析:

看见异或就换二进制。

枚举si和sj,对于每个和,都在字典树里逐位找使得异或结果最大的那个。找之前把si,sj从树里删掉。

注意字典树不一定非要对字符串操作,没必要把数字先变成字符串再操作。对于x, 逐位 x&(1 << i) 就可以得到每一位。同时,找的时候可以直接算出答案,而不用把最优串存下来再算结果。不要拘泥于模板。

代码:

#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
#define ms(a,b) memset(a,b,sizeof(a))
#define lson rt*2,l,(l+r)/2
#define rson rt*2+1,(l+r)/2+1,r
typedef unsigned long long ull;
typedef long long ll;
const int MAXN=1e3+5;
const double EPS=1e-8;
const int INF=0x3f3f3f3f;
const int MOD = 1e9+7;
struct Trie{
int n;
Trie *next[2];
};
Trie tree[MAXN*MAXN];
int n,a[MAXN];
char ans[MAXN];
int tot=-1;
void create(){
++tot;
tree[tot].n=0;
for(int i=0;i<2;i++)
tree[tot].next[i]=NULL;
}
void init(){
tot=-1;
create();
}
void insert(int x){
Trie *r=&tree[0];
for(int i=30;i>=0;i--){
int k = (x & (1 << i)) > 0;
if(r->next[k]){
r=r->next[k];
r->n++;
}
else{
create();
r->next[k]=&tree[tot];
r=&tree[tot];
r->n++;
}
}
}
void erase(int x){
Trie *r=&tree[0];
for(int i=30;i>=0;i--){
int k = (x & (1 << i)) > 0;
r=r->next[k];
r->n--;
}
}
int search(int x){
Trie* r=&tree[0];
int ret = 0;
for(int i=30;i>=0;i--){
int k = !((x & (1 << i)) > 0);
Trie* l1 = r->next[k],*l2 = r->next[1-k];
if(l1 && l1->n){
r = l1;
ret += (1 << i);
}
else{
r = l2;
}
}
return ret;
}

int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
init();
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
insert(a[i]);
}
int Ans = 0;
for(int i=0;i<n;i++){
for(int j=i+1;j<n;j++){
erase(a[i]);
erase(a[j]);
Ans = max(Ans,search(a[i]+a[j]));
insert(a[i])
a930
;
insert(a[j]);
}
}
printf("%d\n",Ans);
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: