Salem(按位异或)

Salem is known to be one of the best competitive programmers in the region. However, he always finds a hard time understanding the concept of the hamming distance. The hamming distance of two numbers is defined as the number of different digits in their binary representations (leading zeros are used if necessary to make the binary representations have the same length). For example the hamming distance between 12 and 5 is 2 since their binary representations are 1100 and 0101 respectively and they differ in the first and fourth positions.



Recently, Salem got a problem that he needs your help to solve. He is given N integers and asked to get the maximum among the hamming distances of all possible pairs of the given integers.


Input
The first line of the input will be a single integer T representing the number of test cases. Followed by T test cases. Each test case will start with a line with single integer (2 ≤ N ≤ 100) representing the number of the integers. Each of the following N lines contains one of the integers (1 ≤ Ai ≤ 10, 000) from the list of the integers.


Output
For each test case print one line consists of one integer representing the maximum hamming distance between all possible pairs from the given integers.


Examples
input
2
2
12
5
3
1
2
3
output
2
2

一般与二进制有关的题目,大多数要用到按位与,按位或,按位异或,该题也是如此。

思路:循环遍历所有可能的结果,每次的异或的结果转化为二进制(用一个递归函数实现,但是不输出二进制,只是统计1的个数) ,也就是说,每两个数相比较后,我可以得到这两个数转化成 二进制后不相同位的个数。假设最大值ans为1,如果两个数想比较后得到的结果大于ans,我就把结果赋给ans。最后输出ans。可恨的是比赛的时候心理素质太差,有个小错误一直没有发现(递归时出现了问题)。

问题代码:

int f(int n)
{
    int m, cnt=0;
    if(n!=0)
    {
        f(n/2);
        m=n%2;
        if(m==1)
          cnt++;
    }
    return cnt;
}

cnt为1的个数,可是cnt 真的是1的个数吗,我输入7,cnt为1.可是cnt应为3才对。我比赛时没想到是递归出了问题,今天静下心来思考时几分钟就发现了问题。。。处理办法很简单,把cnt换成全局变量即可。。比赛时我最后用了itoa函数终于AC。。总算有惊无险。

AC代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
int a[100000];
char str[10000];
int f(int, int);
int main()
{
    int T;
    cin>>T;
    int n, i,j, ans=0, tmp1, tmp2;
    while(T--)
    {
        ans=0;
        tmp2=0;
        cin>>n;
        for(i=0;i<n;i++)
            cin>>a[i];

        for(i=0;i<n-1;i++)
        {

            for(j=i+1;j<n;j++)
            {
                tmp2=0;
                tmp1=a[i]^a[j];
                itoa(tmp1, str, 2);//tmp2=f(tmp1, 2);
                //puts(str);
                for(int k=0;k<strlen(str);k++)
                    if(str[k]=='1')
                        tmp2++;
                if(tmp2>ans)
                    ans=tmp2;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}
改进后的代码:

#include <cstdio>
#include <iostream>
using namespace std;
int a[100000];
char str[10000];
int f(int);
int cnt;
int main()
{
    int T;
    cin>>T;
    int n, i,j, ans=0, tmp;
    while(T--)
    {
        ans=0;
        cin>>n;
        for(i=0;i<n;i++)
            cin>>a[i];

        for(i=0;i<n-1;i++)
        {

            for(j=i+1;j<n;j++)
            {
                cnt=0;
                tmp=a[i]^a[j];
                f(tmp);
                if(cnt>ans)
                    ans=cnt;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

int f(int n)
{
    int m;

    if(n!=0)
    {
        f(n/2);
        m=n%2;
        if(m==1)
           cnt++;
    }
}



你可能感兴趣的:(位运算,二进制)