XOR Clique 水題,異或運算
(做題實在沒有思路的時候可以研究研究案例)
題目:
BaoBao has a sequence a1,a2,...,an. He would like to find a subset S of {1,2,...,n} such that ∀i,j∈S, ai⊕aj<min(ai,aj) and ∣S∣ is maximum, where ⊕ means bitwise exclusive or.
輸入:
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 (1≤n≤), indicating the length of the sequence.
The second line contains n integers: a1,a2,...,an (1≤ai≤), indicating the sequence.
It is guaranteed that the sum of n in all cases does not exceed .
輸出:
For each test case, output an integer denoting the maximum size of S.
樣例輸入:
3
3
1 2 3
3
1 1 1
5
1 2323 534 534 5
樣例輸出:
2
3
2
題意:
題目很好理解,有一個a1到an的序列,問能不能找到一個長度為S的序列,對於在S裡面的任意的i,j滿足ai⊕aj<min(ai,aj) 這個條件,兩個數的異或小於這兩個數的最小值,要求輸出S的最大長度。
分析一下案例:
1.1的二進位制是1,2的二進位制是10,3的二進位制是11
2.1的二進位制是1
3.1的二進位制是1,2323的二進位制是100100010011,534的二進位制是1000010110,5的二進位制是101
由分析可得,第一個案例最大長度為2,裡面的元素有2,3
第二個案例最大長度為3,裡面的元素有1,1,1
第三個案例最大長度為2,裡面的元素有534,534
到這裡可以看出只有二進位制位數相同的數進行異或運算才會小於他們的最小值。
所以這個題只要求相同位數的數有多少個,輸出最多的那個就好了。如果兩個數都滿足n>=pow(2,i)&&n<pow(2,i+1)(n代表任意一個數),那麼這兩個數的二進位制位數就相同。
AC程式碼:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;
const int N=120;
int a[120];
int dis[120];
int main()
{
int t;
scanf("%d",&t);
dis[0]=1;
for(int i=1;i<N;i++)//用pow表示2的n次方會超時,所以這裡用一個數組初始化2的n次方
dis[i]=dis[i-1]*2;
while(t--)
{
int n,s;
int maxx=0;
memset(a,0,sizeof(a));
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&s);
for(int j=0;;j++)
{
if(s>=dis[j]&&s<dis[j+1])
{
a[j]++;//如果這個數滿足條件,對應的j就+1
maxx=max(maxx,a[j]);//每次都跟前面的a[j]比較,最後要最大的
break;
}
}
}
printf("%d\n",maxx);
}
return 0;
}