杭电 4712 汉明距

暴力+剪枝,或者使用随机化算法,因为结果总是在0-20之间,所以任选两个求汉明距,它不是最终结果的概率应该不超过19/20,当随机生成10^5组数据时,求出的最小值不是最终结果的概率非常低。同时当结果为0或者1时能较快的判断出来,可以特判这两种情况。

我的加了特判的代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<ctime>
 5 using namespace std;
 6 const int N = 100005;
 7 int a[N],n;
 8 bool vis[(1<<20) + 100];
 9 inline bool is1()
10 {
11     for(int i=0; i<n; ++i)
12         for(int j=0; j<20; ++j)
13             if(vis[a[i]^(1<<j)]) return true;
14     return false;
15 }
16 inline int ham(int x,int y)
17 {
18     int cnt = 0;
19     int d = a[x]^a[y];
20     for(int i=0; i<20; ++i)
21         if(d&(1<<i)) ++cnt;
22     return cnt;
23 }
24 int memte(int t)
25 {
26     int ans = 21;
27     srand((unsigned)time(NULL));
28     while(t--)
29     {
30         int a = rand()%n;
31         int b = rand()%n;
32         if(a == b) b = (a+1)%n;
33         int tmp = ham(a,b);
34         if(ans > tmp) ans = tmp;
35     }
36     return ans;
37 }
38 int main()
39 {
40 //    freopen("in.txt","r",stdin);
41     int T;
42     scanf("%d",&T);
43     while(T--)
44     {
45         scanf("%d",&n);
46         memset(vis,0,sizeof(vis));
47         bool flag = false;
48         for(int i=0; i<n; ++i)
49         {
50             scanf("%X",&a[i]);
51             if(!vis[a[i]]) vis[a[i]] = 1;
52             else flag = true;
53         }
54         if(flag) printf("0\n");
55         else
56         {
57             flag = is1();
58             if(flag) printf("1\n");
59             else printf("%d\n",memte(100000));
60         }
61     }
62     return 0;
63 }
View Code

运行时间为300多ms.

没加任何特判的。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cstdlib>
 4 #include<ctime>
 5 using namespace std;
 6 const int N = 100005;
 7 int a[N],n;
 8 inline int ham(int x,int y)
 9 {
10     int cnt = 0;
11     int d = a[x]^a[y];
12     for(int i=0; i<20; ++i)
13         if(d&(1<<i)) ++cnt;
14     return cnt;
15 }
16 int memte(int t)
17 {
18     int ans = 21;
19     srand(time(NULL));
20     while(t--)
21     {
22         int a = rand()%n;
23         int b = rand()%n;
24         if(a == b) b = (a+1)%n;
25         int tmp = ham(a,b);
26         if(ans > tmp) ans = tmp;
27         if(ans == 0 ) break;
28     }
29     return ans;
30 }
31 int main()
32 {
33 //    freopen("in.txt","r",stdin);
34     int T;
35     scanf("%d",&T);
36     while(T--)
37     {
38         scanf("%d",&n);
39         for(int i=0; i<n; ++i)
40             scanf("%X",&a[i]);
41         printf("%d\n",memte(1000000));
42     }
43     return 0;
44 }
View Code

运行时间接近3s,测试10^6,如果只测10^5就WA,10^7就会超时

posted on 2013-09-10 16:41  allh123  阅读(212)  评论(0编辑  收藏  举报

导航