一天一道算法题---6.4--中途相遇法

感谢微信平台 --- 一天一道算法题 ---- 每天多一点进步----

直接上题目了:

    touch me

因为 我实在还没有理解这个算法的核心..... stupid as i am

so I can't tell anything.....

我的一些疑问 同样 附在了 我下面给出的代码中

 1 /*
 2 总的思路:-----都是来自 刘汝佳的算法书P58 ------
 3 用二进制的位 表示字母   1表示出现奇数次  0 表示出现偶数次
 4 根据相同的两个数 xor 为0  将字符串 分成2个部分
 5 首先计算前 n/2个字符串所能得的所有xor值 并将其保存到一个映射S中( xor值->前n/2个字符串中的一个子集)
 6 然后 枚举后n/2个字符串所能得到的所有xor值 并每次都在S中查找
 7 映射 通过stl中的map实现 ---  
 8 这种 方法 称为  中途相遇法
 9 */
10 
11 #include <iostream>
12 #include <map>
13 #include <cstdio>
14 using namespace std;
15 
16 const int size = 24;
17 map<int,int>table;
18 int bitcount( int x )   //这个函数作用 我没看懂
19 {
20     return x==0?0:bitcount(x/2)+(x&1);
21 }
22 
23 int A[size];
24 char str[1010];
25 
26 int main()
27 {
28     int n;
29     while( ~scanf("%d",&n) &&n )
30     {
31         for( int i = 0 ; i<n ; i++ )
32         {
33             scanf( "%s",str );
34             A[i] = 0;
35             for( int j = 0 ; str[j]!='' ; j++ )
36             {
37                 A[i]^=( 1<<(str[j]-'A') );
38             } // 这个 for 循环的作用   将每个字符串对应一个相应的值(这里它用位运算 可以理解为一种哈希映射吗?)
39         }     // 我想 这样映射过去 应该是可以出现 字符串不同 但值相同情况  如 ABB 与 AC  这样没影响的吗?
40         table.clear();
41         int n1 = n/2; // 这里 如果 写成 int n1 = n/2?(n+1)/2:n/2; 判断下 n的奇偶性来/2 有什么影响吗
42         int n2 = n-n1;
43         for( int i = 0 ; i<(1<<n1) ; i++ ) // 这里 ( i <( 1<<n1 ) )中 1<<n1没懂
44         {
45             int x = 0;
46             for( int j = 0 ; j<n1 ; j++ )
47             {
48                 if( i & (1<<j) )  // 这里的 按位与操作 是有什么目的?
49                 {
50                     x^=A[j];
51                 }
52             }
53             if( !table.count(x) || bitcount( table[x]) < bitcount(i) )
54             {
55                 table[x] = i;  
56             }
57         }
58         int ans = 0; // ans又有什么作用呢?
59         for( int i = 0 ; i<(1<<n2) ; i++ )
60         {
61             int x = 0;
62             for( int j = 0 ; j<n2 ; j++ )
63             {
64                 if( i & (1<<j) )
65                 {
66                     x^=A[n1+j];
67                 }
68             }
69             if( table.count(x) && bitcount(ans) < bitcount(table[x]) +bitcount(i) )
70             {
71                 ans = (i<<n1)^table[x];
72             }
73         }
74         printf( "%d
",bitcount(ans) );
75         for( int i = 0 ; i<n ; i++ )
76         {
77             if( ans & (1<<i) )
78             {
79                 printf( "%d ",i+1 );
80             }
81         }
82         printf( "
" );
83     }
84     return 0;
85 }
86 
87 
88 
89 
90 
91 
92 
93 // 按位与  两位同时为1 才是1    x&1 --读取x的最低位
94 // 按位或  有一位是1 就是1
95 // 异或    两位相同 是0  否则是1
96 // 取反  1变成0  0变成1
View Code

-----a sorrow story------

just follow your heart
原文地址:https://www.cnblogs.com/radical/p/3773524.html