一天一道算法题---6.4--中途相遇法
感谢微信平台 --- 一天一道算法题 ---- 每天多一点进步----
直接上题目了:
因为 我实在还没有理解这个算法的核心..... 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]!='\0' ; 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\n",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( "\n" ); 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
-----a sorrow story------
just follow your heart