• 一天一道算法题---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
  • 相关阅读:
    Android:UI界面设计基础知识总结(一)
    Test:河北金力集团企业网集成
    Java中的异常处理try catch(第八周课堂示例总结)
    Java第七周课堂示例总结
    初入JavaWeb(半成品)
    Redis详解(4)--redis底层数据结构
    Go语言流程控制05--defer延时执行
    java==IO练习,文件切割合拼工具开发代码
    【洛谷 P3772】[CTSC2017]游戏(矩阵乘法+线段树)
    【LOJ #2865】「IOI2018」狼人(Kruscal重构树+扫描线)
  • 原文地址:https://www.cnblogs.com/radical/p/3773524.html
Copyright © 2020-2023  润新知