百度之星 1003 Xor Sum
2014-05-18 20:17
183 查看
Problem Description
Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?
Input
输入包含若干组测试数据,每组测试数据包含若干行。
输入的第一行是一个整数T(T < 10),表示共有T组数据。
每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。
Output
对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
对于每个询问,输出一个正整数K,使得K与S异或值最大。
Sample Input
2
3 2
3 4 5
1
5
4 1
4 6 5 6
3
Sample Output
Case #1:
4
3
Case #2:
4
本来想用int卡过去的,但是实践证明,不行。runtime error(系统提示爆栈)了好多次。
后来改成了__int64 就是开始wa了。期间也改了记录数值的方式,但依然是错的。这个题真不知道改怎么做了。
有没有路过的好心人帮忙纠正一下错误的?
首先,先贴一发 runtime error的代码
然后,再来贴一发wa的代码。其中记录方式也有改变
求大神指明前进的方向。ORZ
此题已解决。以上两个代码可能是在十进制转换为二进制的并且以数组进行运算的时候出现了错误。32?31?33?没有弄对。当然,也只是可能罢了。
今天,换了一种方式,A掉了。此题get。代码贴之(字典树,数组模拟版):
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <stack>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL __int64
#define MAX 3200000
struct node
{
LL data;
int num0,num1;
} nod[MAX];
LL num,tem;
void build(int index,LL a)
{
LL two=tem;
while(two>0)
{
if((a&two)!=0)
{
if(nod[index].num1==-1)
nod[index].num1=num++;
index=nod[index].num1;
}
else
{
if(nod[index].num0==-1)
nod[index].num0=num++;
index=nod[index].num0;
}
two=two>>1;
}
nod[index].data=a;
// cout<<index<<endl;
}
LL query(int index,LL a)
{
LL two=tem;
while(two>0)
{
if((a&two)==0)
{
if(nod[index].num1==-1)
index=nod[index].num0;
else index=nod[index].num1;
}
else
{
if(nod[index].num0==-1)
index=nod[index].num1;
else index=nod[index].num0;
}
two=two>>1;
}
// cout<<index<<"!"<<endl;
return nod[index].data;
}
void pre(int n)
{
tem=1;
for(int i=0; i<n; i++)
tem*=2;
}
void init(int n)
{
for(int i=0; i<n; i++)
{
nod[i].data=nod[i].num0=nod[i].num1=-1;
}
}
int main()
{
int T,n,m,i,j,k;
LL x;
pre(32);
scanf("%d",&T);
for(int cs=1; cs<=T; cs++)
{
init(MAX);
num=1;
scanf("%d%d",&n,&m);
for(i=0; i<n; i++)
{
scanf("%I64d",&x);
build(0,x);
}
printf("Case #%d:\n",cs);
for(i=0; i<m; i++)
{
scanf("%I64d",&x);
printf("%I64d\n",query(0,x));
}
}
return 0;
}
Zeus 和 Prometheus 做了一个游戏,Prometheus 给 Zeus 一个集合,集合中包含了N个正整数,随后 Prometheus 将向 Zeus 发起M次询问,每次询问中包含一个正整数 S ,之后 Zeus 需要在集合当中找出一个正整数 K ,使得 K 与 S 的异或结果最大。Prometheus 为了让 Zeus 看到人类的伟大,随即同意 Zeus 可以向人类求助。你能证明人类的智慧么?
Input
输入包含若干组测试数据,每组测试数据包含若干行。
输入的第一行是一个整数T(T < 10),表示共有T组数据。
每组数据的第一行输入两个正整数N,M(<1=N,M<=100000),接下来一行,包含N个正整数,代表 Zeus 的获得的集合,之后M行,每行一个正整数S,代表 Prometheus 询问的正整数。所有正整数均不超过2^32。
Output
对于每组数据,首先需要输出单独一行”Case #?:”,其中问号处应填入当前的数据组数,组数从1开始计算。
对于每个询问,输出一个正整数K,使得K与S异或值最大。
Sample Input
2
3 2
3 4 5
1
5
4 1
4 6 5 6
3
Sample Output
Case #1:
4
3
Case #2:
4
本来想用int卡过去的,但是实践证明,不行。runtime error(系统提示爆栈)了好多次。
后来改成了__int64 就是开始wa了。期间也改了记录数值的方式,但依然是错的。这个题真不知道改怎么做了。
有没有路过的好心人帮忙纠正一下错误的?
首先,先贴一发 runtime error的代码
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <stack> #include <vector> #include <queue> #include <algorithm> #include <iostream> using namespace std; struct node { int data;//data记录那个具体的数字 node *num0; node *num1; }; void build(int a[],node *head,int leave,int num)//建树 { if(leave<0)return ; if(a[leave]==1) { if(head->num1==NULL) { node *tem=new node(); head->num1=tem; tem->num0=NULL; tem->num1=NULL; if(leave==0) { tem->data=num; } else build(a,tem,leave-1,num); } else build(a,head->num1,leave-1,num); } else { if(head->num0==NULL) { node *tem=new node(); head->num0=tem; tem->num0=NULL; tem->num1=NULL; if(leave==0) { tem->data=num; } else build(a,tem,leave-1,num); } else build(a,head->num0,leave-1,num); } } int query(int a[],int leave,node *head)//查询 如果询问的数在该位置为1为使异或值最大,则查询字典树里为0的值,相反亦然 { if(leave<0)return head->data; if(head->num0==NULL&&head->num1==NULL)return -1; if(a[leave]==1) { if(head->num0!=NULL)return query(a,leave-1,head->num0); return query(a,leave-1,head->num1);//如果字典树里没有0的值则往1处搜索 } else if(a[leave]==0) { if(head->num1!=NULL)return query(a,leave-1,head->num1); return query(a,leave-1,head->num0); } return -1; } int b[55]; void toBase(int num)//将一个数字转化为二进制 { memset(b,0,sizeof(b)); int i=0; while(num) { b[i++]=num&1; num=num>>1; } } void det(node *head)//内存释放,后来发现re不是这个错误T^T { if(head->num0!=NULL)det(head->num0); if(head->num1!=NULL)det(head->num1); free(head); } int main() { int T,n,m,i,j,k,x,y; scanf("%d",&T); for(int cs=1; cs<=T; cs++) { scanf("%d%d",&n,&m); node *head=new node(); head->num0=head->num1=NULL; for(i=0; i<n; i++) { scanf("%d",&x); toBase(x); build(b,head,33,x); } printf("Case #%d:\n",cs); for(i=0; i<m; i++) { scanf("%d",&x); toBase(x); int ans=query(b,33,head); printf("%d\n",ans); } // det(head); } return 0; }
然后,再来贴一发wa的代码。其中记录方式也有改变
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <stack> #include <vector> #include <queue> #include <algorithm> #include <iostream> using namespace std; #define LL __int64 struct node { int data;//data只保存0或者1的值,具体数值根据路径上的值读取 node *num0; node *num1; }; void build(int a[],node *head,int leave) { if(leave<0)return ; if(a[leave]==1) { if(head->num1==NULL) { node *tem=new node(); head->num1=tem; tem->num0=NULL; tem->num1=NULL; tem->data=1; build(a,tem,leave-1); } else build(a,head->num1,leave-1); } else { if(head->num0==NULL) { node *tem=new node(); head->num0=tem; tem->num0=NULL; tem->num1=NULL; tem->data=0; build(a,tem,leave-1); } else build(a,head->num0,leave-1); } } LL ans,tem; void query(int a[],int leave,node *head) { ans+=(head->data)*tem; tem/=2; if(head->num0==NULL&&head->num1==NULL)return ; if(a[leave]==1) { if(head->num0!=NULL)query(a,leave-1,head->num0); else query(a,leave-1,head->num1); return ; } else if(a[leave]==0) { if(head->num1!=NULL) query(a,leave-1,head->num1); else query(a,leave-1,head->num0); return ; } return ; } int b[55]; void toBase(LL num) { memset(b,0,sizeof(b)); int i=0; while(num) { b[i++]=num%2; num/=2; } } void det(node *head) { if(head->num0!=NULL)det(head->num0); if(head->num1!=NULL)det(head->num1); free(head); } int main() { int T,n,m,i,j,k; LL x,y; y=1; for(j=0; j<33; j++) y*=2; scanf("%d",&T); for(int cs=1; cs<=T; cs++) { scanf("%d%d",&n,&m); node *head=new node(); head->num0=head->num1=NULL; head->data=0; for(i=0; i<n; i++) { scanf("%I64d",&x); toBase(x); build(b,head,32); } printf("Case #%d:\n",cs); for(i=0; i<m; i++) { scanf("%I64d",&x); toBase(x); ans=0; tem=y; query(b,32,head); printf("%I64d\n",ans); } // det(head); } return 0; }
求大神指明前进的方向。ORZ
此题已解决。以上两个代码可能是在十进制转换为二进制的并且以数组进行运算的时候出现了错误。32?31?33?没有弄对。当然,也只是可能罢了。
今天,换了一种方式,A掉了。此题get。代码贴之(字典树,数组模拟版):
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <stack>
#include <vector>
#include <queue>
#include <algorithm>
#include <iostream>
using namespace std;
#define LL __int64
#define MAX 3200000
struct node
{
LL data;
int num0,num1;
} nod[MAX];
LL num,tem;
void build(int index,LL a)
{
LL two=tem;
while(two>0)
{
if((a&two)!=0)
{
if(nod[index].num1==-1)
nod[index].num1=num++;
index=nod[index].num1;
}
else
{
if(nod[index].num0==-1)
nod[index].num0=num++;
index=nod[index].num0;
}
two=two>>1;
}
nod[index].data=a;
// cout<<index<<endl;
}
LL query(int index,LL a)
{
LL two=tem;
while(two>0)
{
if((a&two)==0)
{
if(nod[index].num1==-1)
index=nod[index].num0;
else index=nod[index].num1;
}
else
{
if(nod[index].num0==-1)
index=nod[index].num1;
else index=nod[index].num0;
}
two=two>>1;
}
// cout<<index<<"!"<<endl;
return nod[index].data;
}
void pre(int n)
{
tem=1;
for(int i=0; i<n; i++)
tem*=2;
}
void init(int n)
{
for(int i=0; i<n; i++)
{
nod[i].data=nod[i].num0=nod[i].num1=-1;
}
}
int main()
{
int T,n,m,i,j,k;
LL x;
pre(32);
scanf("%d",&T);
for(int cs=1; cs<=T; cs++)
{
init(MAX);
num=1;
scanf("%d%d",&n,&m);
for(i=0; i<n; i++)
{
scanf("%I64d",&x);
build(0,x);
}
printf("Case #%d:\n",cs);
for(i=0; i<m; i++)
{
scanf("%I64d",&x);
printf("%I64d\n",query(0,x));
}
}
return 0;
}
相关文章推荐
- 2014 百度之星 1003 题解 Xor Sum
- 2014 百度之星 1003 题解 Xor Sum
- 2017"百度之星"程序设计大赛 - 资格赛 1003 度度熊与邪恶大魔王
- 【2017"百度之星"程序设计大赛资格赛 1003】度度熊与邪恶大魔王(DP 背包问题)
- 百度之星2015资格赛1003 IP聚合 模拟题
- 百度之星初赛(1) 1003 序列变换 二分搜索
- 2015百度之星资格赛1003
- BestCoder 2015百度之星资格赛1003 IP聚合 -
- 2015百度之星资格赛1003
- bestcoder 百度之星 1003 IP聚合
- 2017百度之星资格赛 1003 度度熊与邪恶大魔王
- ip聚合(百度之星资格赛1003)
- 百度之星 2015 初赛(2) 1003 棋盘占领
- 2016百度之星复赛 1003 拍照 优先队列
- 2017百度之星-1003-度度熊与邪恶大魔王(完全背包)
- 2017百度之星资格赛:1003. 度度熊与邪恶大魔王
- 2015百度之星1003
- 2015百度之星初赛1 1003(二分)
- 2017百度之星 资格赛 1003 度度熊与邪恶大魔王(dp)
- 2017百度之星资格赛 1002-图 1003-DP 1004-01背包(解选择方案)