zoukankan      html  css  js  c++  java
  • zoj 3870 Team Formation

    题意:

    给出n个数,问做多可以找到多少对数字A,B,使得A xor B > max(A,B)。

    思路:

    感谢mzjj教本弱智。

    对于一个数,只考虑小于它的数字。

    假设对于一个数字x 11001001,对于从最高位开始的连续的1,满足条件的数y的这位一定不能为1,从碰到的第一位0开始:这一位就可以是1,后面无论是什么都可以满足条件;

    如果这位不为1,那么直到碰到下一个0之前,都不能是1。

    所以可以从小到大枚举,按最高位分组,对于当前来到的x,枚举它的0的位有多少,答案加上以这位为最高位的数字的个数。

    然后把这个数字加进分组中。

    一开始把b数组只开了10,以为10的9次方最多10位,确实是,但是那是10进制,二进制就是32位了,睿智了Orz。

    我的代码:

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <algorithm>
     4 using namespace std;
     5 const int N = 1e5 + 10;
     6 int a[N];
     7 int b[35];
     8 int main()
     9 {
    10     int t;
    11     scanf("%d",&t);
    12     while (t--)
    13     {
    14         memset(b,0,sizeof(b));
    15         int n;
    16         scanf("%d",&n);
    17         for (int i = 0;i < n;i++)
    18         {
    19             scanf("%d",&a[i]);
    20         }
    21         sort(a,a+n);
    22         long long ans = 0;
    23         for (int i = 0;i < n;i++)
    24         {
    25             int x = a[i];
    26             int cnt = 0;
    27             while (x)
    28             {
    29                 if (!(x & 1)) ans += b[cnt];
    30                 cnt++;
    31                 x >>= 1;
    32             }
    33             if (cnt == 0) continue;
    34             b[cnt-1]++;
    35         }
    36         printf("%lld
    ",ans);
    37     }    
    38     return 0;
    39 }

    学长的代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long LL;
     4 const int N = 1e5 + 5;
     5 int T, n;
     6 int a[N];
     7 int cnt[33];
     8 
     9 int main() {
    10     scanf("%d", &T);
    11     while(T--) {
    12         scanf("%d", &n);
    13         for(int i = 0; i < n; i++) {
    14             scanf("%d", &a[i]);
    15         }
    16         sort(a, a+n);
    17         memset(cnt, 0, sizeof(cnt));
    18         LL ans = 0;
    19         for(int i = 0; i < n; i++) {
    20             int x = a[i];
    21             int b = 31 - __builtin_clz(x);//返回左起第一个‘1’之前0的个数。
    22             for(int j = 0; j < b; j++) {
    23                 if(~x&(1<<j)) ans += cnt[j];
    24             }
    25             cnt[b]++;
    26         }
    27         printf("%lld
    ", ans);
    28     }
    29     return 0;
    30 }
  • 相关阅读:
    SuperMap房产测绘成果管理平台
    SuperMap产权登记管理平台
    Android adb shell am 的用法(1)
    由浅入深谈Perl中的排序
    Android 内存监测和分析工具
    Android 网络通信
    adb server is out of date. killing...
    引导页使用ViewPager遇到OutofMemoryError的解决方案
    adb logcat 详解
    How to send mail by java mail in Android uiautomator testing?
  • 原文地址:https://www.cnblogs.com/kickit/p/9000699.html
Copyright © 2011-2022 走看看