用字典树思想来做。对于一个数,给出他的二进制,然后更具二进制建立字典树,然后每次询问的时候的数也给出二进制,如果当前为1,那就向0走,为0,向1走。
#include<stdio.h> #include<string.h> const int maxn = 100010; struct node { int flag; int num; node *next[2]; void init() { next[0]=next[1]=NULL; num=0; flag=-1; } }; node *trie,*p=NULL; int a[maxn],n,m; void init() { trie=new node; trie->init(); } void add(int x) { int i,j; for(i=30; i>=0; i--) { int t; if(x&(1<<i))t=1; else t=0; if(t) { if(p->next[t]==NULL) { node *q=new node; q->init(); p->next[t]=q; } p=p->next[t]; p->num++; } else { if(p->next[t]==NULL) { node *q=new node; q->init(); p->next[t]=q; } p=p->next[t]; p->num++; } } p->flag=x; } int query(int x) { int ret=0; int i,j; for(i=30; i>=0; i--) { int t; if(x&(1<<i)) t=1; else t=0; if(t) { if(p->next[0]!=NULL) p=p->next[0]; else p=p->next[1]; } else { if(p->next[1]!=NULL) p=p->next[1]; else p=p->next[0]; } } return p->flag; } void Del(node *trie) { for(int i=0;i<=1;i++) { if(trie->next[i]!=NULL) Del(trie->next[i]); } delete trie; } int main() { int i,t,j,ff=0; scanf("%d",&t); while(t--) { init(); scanf("%d%d",&n,&m); for(i=0; i<n; i++) { p=trie; scanf("%d",&a[i]); add(a[i]); } printf("Case #%d: ",++ff); while(m--) { int x; p=trie; scanf("%d",&x); printf("%d ",query(x)); } Del(trie); } }