XOR Clique(按位异或)

XOR Clique(按位异或):

传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4057

准备:异或:参加运算的两个数据,按二进制位进行“异或”运算。

                      运算规则:0^0=0,   0^1=1, 1^0=1,    1^1=0;

                      即:参加运算的两个对象,如果两个相应位为“异”,则该位结果为1,否则为0;

 

 

题意:

有一个a1到an的序列,问能不能找到一个长度为S的序列,对于在S里面的任意的i,j满足a​i​​⊕a​j​​<min(a​i​​,a​j​​) 这个条件,两个数的异或小于这两个数的最小值,要求输出S的最大长度。

解题思路:

多找几组数据就会发现若想异或结果小于最小值,只需要两个数二进制形式位数相同, 即二进制前面第一位都为1,进行异或运算后就会第一位变为0,自然比原来两个数都小 所以只需要将序列中所有数的二进制形式位数进行统计即可(学长说二进制运算一般找最高位是常用的方法)

以下为AC代码:

 1 /* */
 2 # include <bits/stdc++.h>
 3 using namespace std;
 4 typedef long long ll;
 5 
 6 const int INF = 0x3f3f3f3f;
 7 const int MAXN = 40;///用来记录路最高位的值,2的30次方就可以达到1e9
 8 int a[MAXN];///用来记录某一最高位所包含的数有几个
 9 
10 
11 int bt(int x)
12 {
13     int cnt = 0;
14     while( x )
15     {
16         x >>= 1;///x除以2,10进制化2进制运算
17         cnt++;
18     }
19     return cnt;///返回最高位
20 }
21 
22 int main()
23 {
24     int T
25     cin >> T;
26     while( T-- )
27     {
28         memset(a, 0, sizeof(a));
29         int n;
30         scanf("%d", &n);
31         int ans = 0;
32         for( int i=0; i<n; i++ )
33         {
34             int e;
35             scanf("%d", &e);
36             ans = max(ans, ++a[bt(e)]);///找出最高位为bt(e)的值的个数,找出哪一最高位对应的数最多,极为最长子集包含的数的个数
37         }
38         printf("%d\n", ans);
39     }
40     return 0;
41 }
View Code

 

以下为超时代码:

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int main()
 4 {
 5     int t;
 6     scanf("%d", &t);
 7     while (t--)
 8     {
 9         int n;
10         int a[100005]={0};///相当于建了一个桶来标记
11         scanf("%d", &n);
12         int k=0;
13         for (int i = 0; i < n; ++i)
14         {
15             int x,sum=0;
16             scanf("%d", &x);
17             while(x)
18             {
19                 sum++;
20                 x/=2;
21             }
22             a[sum]++;
23         }
24        for(int i=0;i<10000;i++)///这样遍历,无用循环做的次数太多了,所以超时
25        {
26            k=max(k,a[i]);
27        }
28         printf("%d\n",k );
29     }
30     return 0;
31 }
View Code

 

转载于:https://www.cnblogs.com/wsy107316/p/10872059.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值