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

    题目大意:所给的一个数组中任意两个数异或值大于这个两个数,即i^j > max(i, j),问有多少个这样的异或

    1^1 = 0,  0^0 = 0,  1^0 = 1, 0^1 = 1

    如果x的最高位i位是1,y的位是0,且y比x大,i不是y的最高位,异或后这一位变成1,且yi位以前的1也可以保存,则异或后肯定比两个数的最大值还大

    先把数组用快排从大到小排一下序, 再把每个数转分别换为二进制,在二进制中是 0 的就在相应的位置加 1, 另外如果首位是 1 的话,就把 ans(最后求的值) 加上相应位置上的值

    举个例子:

    1 2 3 4 5 

    快排后是: 5 4 3 2 1 

    对应的二进制是: 

     0  0  0  0

         1  0  1  b[1]++;

         1  0  0  b[1]++,  b[0]++;

             1  1  ans+= b[1];

             1  0  b[0]++,  ans+= b[1];

                 1  ans+= b[0];

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define N 100010
    
    int ans, a[N], b[110], c[110];//注意b,c的数组不能开太大,否则TLE(开始为图省事直接用N,直接TLE)
    
    int cmp(const void *a, const void *b)
    {
        return *(int *)b - *(int *)a;
    }
    
    void slove(int n)
    {
        int i, j = 0;
        memset(c, 0, sizeof(c));
        while(n)
        {
            c[j++] = n % 2;
            n /= 2;
        }//将n转化成二进制
        if(c[j - 1])//如果最高位是1与0异或其值必然大于这两个数,所以ans直接加上相应位置的值
            ans += b[j - 1];
        for(i = 0 ; i < j ; i++)
            if(!c[i])
                b[i]++;//c中等待1异或的0元素个加1
    }
    
    int main()
    {
        int n, t, i;
        scanf("%d", &t);
        while(t--)
        {
            ans = 0;
            memset(b, 0, sizeof(b));
            scanf("%d", &n);
            for(i = 0 ; i < n ; i++)
                scanf("%d", &a[i]);
            qsort(a, n, sizeof(a[0]), cmp);
            for(i = 0 ; i < n ; i++)
                slove(a[i]);
            printf("%d
    ", ans);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    模型命名规范
    Jquery 将表单序列化为Json对象
    Failed to read auto-increment value from storage engine错误的处理方法
    css样式表中设置table的第一列的宽度是固定值
    thinkphp中I("parm")用法的注意事项
    获取凌晨00:00:00的时间
    php empty()和isset()的区别
    react续集
    react的笔记整理
    vuex
  • 原文地址:https://www.cnblogs.com/qq2424260747/p/4738486.html
Copyright © 2011-2022 走看看