码迷,mamicode.com
首页 > 其他好文 > 详细

lightoj1272

时间:2018-11-22 02:39:36      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:src   ESS   异或   交换   贪心   存在   nbsp   博客   style   

题意:给你n个数,要你求出这n个数异或以后的最大值.

注:线性基的应用

这个题的题意很残暴啊,一看就明白,也知道是线性基,但是还是搞不太懂线性基的意思。。。。。。。。。。。。。。。。

首先给出几个博客讲线性基的:

http://www.cnblogs.com/ljh2000-jump/p/5869991.html

http://blog.csdn.net/qaq__qaq/article/details/53812883

 然后我的理解觉得这个有点贪心的感觉,这个的构造方法是从上往下,首先我找到一个在(1<<j)位上为1的数,然后把这个数异或其他的数,首先可以确定一点的是不会影响他高数位的数,因为他高数位的数已经全部变成了1,而该数高数位的数是0,这样异或是不会变的,至于下面为什么这样搞,我也不太清楚,接下来是代码:

代码如下: 

技术分享图片
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 int t,n;
 5 ll num[110];
 6 //感觉这有很重的贪心的思想在里面 
 7 //这样的做法是把每行有1的都保存下来了
 8 //那么这样肯定就是最大值了 
 9 void guess(){
10     int j=63,i=1;//为什么等于63,因为63是int范围内的最大值 
11     while(i<=n&&j>=0){
12         int r=i;//记录当前行  
13         for(int k=i;k<=n;k++){//这个搞可以确定已经处理好的前几行 
14             if((num[k]>>j)&1){ //完全变成最大值,可以不用管上面的几个值 
15                 r=k; 
16                 break;
17             }
18         }
19         if((num[r]>>j)&1){
20            if(r!=i){
21                    swap(num[i],num[r]);//如果不是当前为,就交换 
22            }
23            for(int k=1;k<=n;k++){
24                    if(i!=k&&((num[k]>>j)&1)&&((num[i]>>j)&1)) //这两个数的当前位j
25                    //都应该存在 
26                        num[k]^=num[i];
27            }
28            i++;//已经处理好的前几位 
29         }
30         j--;//依次下移位置 
31     }
32 }
33 
34 int main(){
35     int t;
36     scanf("%d",&t);
37     for(int kase=1;kase<=t;kase++){
38         scanf("%d",&n);
39         for(int i=1;i<=n;i++) scanf("%lld",&num[i]);
40         guess();
41         ll ans=0;
42         for(int i=1;i<=n;i++) ans=ans^num[i];
43         printf("Case %d: %lld\n",kase,ans);
44     }
45     return 0;
46 }
View Code

 

lightoj1272

标签:src   ESS   异或   交换   贪心   存在   nbsp   博客   style   

原文地址:https://www.cnblogs.com/pandaking/p/9998440.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!