33,009
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections.Generic;
namespace ConsoleApplication3
{
class Program
{
static void Main(string[] args)
{
int n = 1000*1000;//一百万
//int n = 100;//一百万
List<int> Arr = new List<int>(n);
Random rand = new Random();
for (int i = 0; i < n; i++)
{
Arr.Add(rand.Next(int.MaxValue));
}
int maxDigit = 0;//最高位
List<int> A = new List<int>(Arr);//复制一份做运算。
for (int i = 0; i < A.Count; i++)
{
//O(n)时间找出最高位
int digit = (A[i] == 0) ? 0 : 1 + (int)(Math.Log(A[i]) / Math.Log(2));
if (maxDigit < digit) { maxDigit = digit; }
}
HashSet<int> B = new HashSet<int>();
maxDigit--;
for (int i = 0; i < A.Count; i++)
{
//O(n)时间找出最高位的那些数字,//去掉最高位。记录索引
if (A[i] >> maxDigit > 0)
{
A[i] ^= (1 << maxDigit); //去掉最高位。
B.Add(i);
}
}
//O(最大位数*n)时间,最大位数<32常数,所以还是=O(n)时间,找出最高位的那些数字
while (maxDigit > 1 && B.Count > 1)
{
maxDigit--;
for (int i = 0; i < A.Count; i++)
{
//O(n)时间找出最高位的那些数字,//去掉最高位。
if ((A[i] >> maxDigit) > 0)
{
A[i] ^= (1 << maxDigit);//去掉最高位。
}
else
{
//删除那些不在最高位的B的索引,取交集。
if (B.Contains(i))
{
B.Remove(i);
if (B.Count == 1)
{
break;
}
}
}
}
}
int Boy = Arr[B.First()];
int Girl =-1 ;
int MaxXor = 0;
//O(n)时间找出异或最大值。
for (int i = 0; i < Arr.Count; i++)
{
int Xor = Boy ^ Arr[i];
if (Xor > MaxXor)
{
MaxXor = Xor;
Girl = Arr[i];
}
}
if (B.Count == 1)
{
Console.WriteLine("最大异或数是" + MaxXor + ",是由" + Boy + "和" + Girl + "产生的,总复杂度是O(n)");
}
Console.Read();
}
}
}