Team Formation(位與運算+右移)

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{A, B}).

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
題意分析:題意就是在給定的幾個數中,問有多少個任意兩個數的異或比這兩個數都要大
思路:想要使一個數異或之後變大,找到這個數的二進制爲0的位置,然後看有多少數二進制第一位也在相同位置,有多少個就有多少數可以讓他變大
一個數的二進制第一位數肯定是1,也就是我們要記錄的位置。
在這我先解釋一下右移運算和按位與運算,首先是右移運算,右移就是對於一個二進制數整體向右移動,高位補零,低位捨去,舉個例子例如13這個數對應的二進制數就是1101,右移一位就是110,在右移一位是11,在右移一位爲1,在右移一位就變爲0,上面對應的都是二進制數; 按位與操作 0&0=0; 0&1=0; 1&0=0; 1&1=1
例子:10&9: 0000 1010 & 0000 1001 = 0000 1000 = 8
AC代碼如下:

#include<stdio.h>
#include<string.h>
int book[101000],a[101000];
int main()
{
	int T,i,n,sum,x,sum1;
	scanf("%d",&T);
	while(T--)
	{
		memset(book,0,sizeof(book));//book數組是用來記錄每個數對應二進制數的位數
		scanf("%d",&n);
		sum=0;
		for(i=1;i<=n;i++)
		{
			sum1=0;
			scanf("%d",&a[i]);
			x=a[i];
			while(x)
			{
				sum1++;
				x>>=1;
			}
			book[sum1]++;//找到每個數對應二進制最高位的位置,記錄出現的次數
		}
		for(i=1;i<=n;i++)
		{
			x=a[i];sum1=0;
			while(x)
			{
				sum1++;
				 if(!(x&1))//當找到二進制數爲零的位置時就把在這個位置爲1的數個數加起來
					sum+=book[sum1];
				x>>=1;
			}
		}
		printf("%d\n",sum);
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章