2012百度之星初赛第二场A题解答

       Made By MarsBoy     转载请注明出处

 

今年是我参加Baidu Astar的第一年,身为编程菜鸟的我,知道自己在初赛就挂了,但是挂归挂,题目我还是很想在赛后解答的,于是经过一番功夫,现在将初赛第二场的解题思路和代码贴出来供大家分享。

 

【题目】

度度熊就是要刷排名第一

时间限制:

1000ms

内存限制:

65536kB

描述

一天度度熊在Baidu游戏大厅中发现了一个隐藏的神奇游戏,叫做度度熊的逆袭。度度熊很好奇到底是什么情况,于是就进入了游戏。这个游戏很神奇,游戏会给出n个数Ai,度度熊可以任意从中选取一些数,一个数可以选任意多次。选好之后度度熊得到的分数为度度熊选出的数的Xor(异或)值。度度熊顿时产生了兴趣,决心要刷至Ranklist的第一名。但是度度熊犯难了,度度熊不知道自己给出的方案是不是最好的,于是度度熊找到了你,希望你告诉他对于某个回合,度度熊能得到的最高分和第二高分是多少?

输入

11个数n,接下来1n个整数表示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    转载请注明出处!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值