Made By MarsBoy 转载请注明出处
今年是我参加Baidu Astar的第一年,身为编程菜鸟的我,知道自己在初赛就挂了,但是挂归挂,题目我还是很想在赛后解答的,于是经过一番功夫,现在将初赛第二场的解题思路和代码贴出来供大家分享。
【题目】
度度熊就是要刷排名第一
时间限制:
1000ms
内存限制:
65536kB
描述
一天度度熊在Baidu游戏大厅中发现了一个隐藏的神奇游戏,叫做”度度熊的逆袭”。度度熊很好奇到底是什么情况,于是就进入了游戏。这个游戏很神奇,游戏会给出n个数Ai,度度熊可以任意从中选取一些数,一个数可以选任意多次。选好之后度度熊得到的分数为度度熊选出的数的Xor(异或)值。度度熊顿时产生了兴趣,决心要刷至Ranklist的第一名。但是度度熊犯难了,度度熊不知道自己给出的方案是不是最好的,于是度度熊找到了你,希望你告诉他对于某个回合,度度熊能得到的最高分和第二高分是多少?
输入
第1行1个数n,接下来1行n个整数表示Ai, (0 <= Ai < 2^31, 并且)
1 <= n <= 10^5
输出
输出一行两个数,表示度度熊能够得到的最高分和第二高分为多少
样例输入
2
5 3
样例输出
6 5
【解题思路】
题目说每个数可以取多次,令输入n个数,我们分析容易得,所有可能的组合有:
1.数a[i] 与 数 a[i] 异或,结果为0
2.多个不重复的数异或,记作:a[k1]^a[k2]^a[k3]^......a[km],其中k1,k2,k3.....介于0到n-1(包含0和n-1) ,m<=n
3.由于任意重复的数异或,得值0,而0异或任一值a[k],值仍然是a[k]。故第三类值是a[k],k=0,1,2,3,.....n
经过以上分析之后,我们可以建立一个数组,用于容纳所有可能的情况的异或值,然后利用递归算法求出第二类的所有异或值,加上0,a[0],a[1],a[2]....a[n-1]等数值一起并入数组,组后排序,找到最大和次大的值即可。
【代码--C++】
/*------------------------------Made By MarsBoy 转 载 请 注 明 出 处!--------------------------*/
#include <iostream>
using namespace std;
//----global variables
int num;
int i=0,j=0,k=0;
int ord=0;
int *xorval;
int tmp=0;
//----end global variables
void xorcal(int array[],int st,int llen);
//递归调用,枚举所有可能的排列组合的异或情况
void xorcal(int array[],int st,int llen){
int x=0,y=0;
if(llen==1){
for(x=st+1;x<num;++x)
xorval[ord++]=tmp^array[x];
return;
}
else{
for(x=0;x<num-st-llen;++x){
tmp^=array[st+x+1];
xorcal(array,st+x+1,llen-1);
}
}
}
int jc(int jcv){
int jcval=1;
for(i=1;i<=jcv;++i)
jcval*=i;
return jcval;
}
int main(){
int xorpnum=0,xornum=0;
int m=0,n=0;
int max=0;
int xor_tmp=0;
int sec_ord;
cin>>num;
int jcnum=jc(num);
int *xor=new int[num];
for(i=0;i<num;++i){
cin>>xor[i];
}
for(m=2;m<=num;++m){
xorpnum+=jcnum/(jc(num-m)*jc(m));
}
xornum=xorpnum+num+1;
xorval=new int[xornum];
for(m=num;m>1;--m){
for(n=0;n<=num-m;++n){
tmp=xor[n];
xorcal(xor,n,m-1);
}
}
//将num个输入值赋给异或数组
for(i=0;i<num;++i)
xorval[ord+i]=xor[i];
//赋值结束
xorval[xornum-1]=0;//将0赋值给异或数组
//sort
for(m=0;m<xornum-1;++m){
if(xorval[m]>xorval[m+1])
{
xor_tmp=xorval[m];
xorval[m]=xorval[m+1];
xorval[m+1]=xor_tmp;
}
}
max=xorval[xornum-1];
sec_ord=0;
for(m=0;m<xornum-1;++m){
if(xorval[m]>xorval[sec_ord] && xorval[m]<max)
sec_ord=m;
}
cout<<max<<" "<<xorval[sec_ord];
delete [] xor;
delete [] xorval;
return 0;
}
【测试数据】
1
1
1 0
3
1 5 9
13 12
Made By MarsBoy 转载请注明出处!!