标签:
http://acm.hdu.edu.cn/showproblem.php?pid=4712
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) Total Submission(s): 1610 Accepted Submission(s): 630
分析:
输入n个数,用十六进制的方式输入的,任意选择其中的两个数进行异或,求异或后的数用二进制表示后1的个数最小的是多少?(n<=100000)
这题看了解题报告,大家都说用随机算法,试过了,随机100000次就过了,50000次都不行,但还是不懂这样怎么可以,唯一的解释就是这个值域也就是结果一共只有21个,
得出正确的结果的可能性很大,但是并不能100%保证结果是对的。无语第一次碰见这种算法。
首先,算汉明距离就是二进制异或以后的1的个数,统计1的个数用x&=x-1很快很神奇。
用if(x&1) {count++; x>>=1;} 在位数比较多的时候会慢一些。
然后就是看题解学到的神奇的“随机”! 来取到“任意的两个” 1w次wa,但是10w次就不会,20组testcase ,不会超时。
队友用随机函数在hduoj上交了五次(WA了4次)A了。也是醉啦 ,,,
AC代码:
1 #include<iostream>
2 #include<cstring>
3 #include<string>
4 #include<cmath>
5 #include<cstdio>
6 #include<algorithm>
7 using namespace std;
8 int a[100005];
9
10 int main()
11 {
12 int tes,i,j,k,res,ans;
13 scanf("%d",&tes);
14 while(tes--)
15 {
16 int n;
17 scanf("%d",&n);
18 for(i=0;i<n;i++)
19 scanf("%X",&a[i]); //16进制读取
20
21 res=20; //结果初始为最大20
22 for(i=1;i<=1000000;i++)
23 {
24 j=rand()%n; //随机函数
25 k=rand()%n;
26 if(j==k)
27 continue;
28 ans=0;
29 int tmp=a[j]^a[k]; //抑或
30 while(tmp) //抑或算1的个数,保存到ans中
31 {
32 if(tmp&1)
33 ans++;
34 tmp>>=1;
35 }
36 if(ans<res)
37 res=ans;
38 }
39 cout<<res<<endl;
40 }
41 return 0;
42 }
hduoj 4712 Hamming Distance 2013 ACM/ICPC Asia Regional Online —— Warmup
标签:
原文地址:http://www.cnblogs.com/jeff-wgc/p/4467019.html