百度之星 1003 Xor Sum

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的代码

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值