ZOJ Team Formation

Description:

For an upcoming programming contest, Edward, the headmaster of Marjar University, is forming a two-man team from N students of his university.

Edward knows the skill level of each student. He has found that if two students with skill level A and B form a team, the skill level of the team will be A ⊕ B, where ⊕ means bitwise exclusive or. A team will play well if and only if the skill level of the team is greater than the skill level of each team member (i.e. A ⊕ B > max{AB}).

Edward wants to form a team that will play well in the contest. Please tell him the possible number of such teams. Two teams are considered different if there is at least one different team member.

Input:

There are multiple test cases. The first line of input contains an integer T indicating the number of test cases. For each test case:

The first line contains an integer N (2 <= N <= 100000), which indicates the number of student. The next line contains N positive integers separated by spaces. The ith integer denotes the skill level of ith student. Every integer will not exceed 109.

Output:

For each case, print the answer in one line.

Sample Input:

2
3
1 2 3
5
1 2 3 4 5

Sample Output:

1
6

题意:有n个学生,现在校长希望将这些学生分成两人一组,两个人分成一组的条件是两个人的能力值异或之后大于两个数的最大值,问最多可以分成几组。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

const int N=100010;

int b[100], ans; ///b数组存放的是第i个位置有多少个0需要1来异或

int cmp(const void *a, const void *b)
{
    return *(int *)b - *(int *)a;
}
void Change(int a)
{
    int c[100], k = 0, i; ///c数组存放每个十进制数转换为二进制之后的数

    while (a)
    {
        c[k++] = a % 2;
        a /= 2;
    }

    ans += b[k-1]; ///转换为二进制时是倒着存放的,所以该二进制的最高位是数组c最后存放的数,只需要加上这一位置上有多少个需要异或的0(如果不是最高位进行异或的话,异或的结果可能会变小)
    for (i = 0; i < k; i++)
        if (!c[i]) b[i]++; ///当数组c的元素为0时,数组b需要将该位置上等待异或的0的个数加1
}

int main ()
{
    int T, n, i, a[N];

    scanf("%d", &T);

    while (T--)
    {
        scanf("%d", &n);
        for (i = 0; i < n; i++)
            scanf("%d", &a[i]);

        qsort(a, n, sizeof(a[0]), cmp); ///从大到小进行排序,因为只有小数和大数进行异或,值才能大于最大值
        
        memset(b, 0, sizeof(b));
        ans = 0;

        for (i = 0; i < n; i++)
            Change(a[i]);

        printf("%d
", ans);
    }

    return 0;
}
原文地址:https://www.cnblogs.com/syhandll/p/4737549.html