zoukankan      html  css  js  c++  java
  • codeforces C. Vasily the Bear and Sequence 解题报告

    题目链接:http://codeforces.com/problemset/problem/336/C

    题目意思:给出一个递增的正整数序列 a1, a2, ..., an,要求从中选出一堆数b1, b2, ..., bk,这堆数进行完按位&运算之后(b1 and b2 and ... and bk),能被2v整除。除此,还要求所选中的这堆数是两两不同的,&之后要最大,换句话来说,v 要尽可能最大,如果找到最大的v的方法有多种,即在 a1, a2, ..., an 中有很多种不同的组合 & 完后能求得最大的v,则挑中的这堆数要尽可能最多。如果得到最多的数还是有多种,只需要写出其中一种即可,如果没找到符合条件的v,则输出-1。

           这道题目想了4天多,看来要做出一条综合题的题目真的需要花费很长时间。一开始很天真的以为,暴力从a1往an搜,一个一个&,如果&完之后的结果是0,则置从&中最后运算完的数开始重新初始化。即假设给出序列1 2 3 4 5,1&2之后会等于0,于是不要&前的1,从2开始继续&,2&3......,直到最后一个数&完为止即可。很明显,这是不符合题意的,因为不能保证v最大。

         (例如,给出10个数

             109070199    215498062    361633800    406156967    452258663

             530571268    670482660    704334662    841023955    967424642

           错误的解法会得出  704334662    841023955    967424642, &的结果是

    1,0000,0001,0000,1000,0000,1000,0010,v = 1。

           而正确的结果是    361633800    406156967   452258663    530571268   841023955   967424642, &的结果是1,0000,0000,0000,0000,0000,0000,0000,v = 28。)

          看来,&完之后的结果大并不意味着v会更大。关键取决于v的右边的0尽可能最多。

          正确的思路:进行两轮筛选。考虑到 an 最大为109 ,且要使v最大,那么应该从v = 31(109 约为 2^30)开始遍历序列,分别尝试与序列中的每个数相&,如果不为0,代表这个数的第 v 位为1,把这个数先保存下来(第一轮筛选,并不保证是最后的结果), 接着从这些被筛选出的数中验证哪些符合第 v-1~1 位与一个第 v-1~1 位都为1的数(也就是下面所说的temp) 相&等于0,符合的就代表v是最优的,则为结果。题目的关键是设置一个临时变量temp,其从第1位到第v-1位都是1,每次将满足第v位为1的,与这个变量做&操作。

          能得到这个思路,很谢谢hdu 群的silence,深感位运算的基础没打好啊,要继续努力才行。

          

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <stdlib.h>
     4 using namespace std;
     5 
     6 const int maxn = 100000 + 5;
     7 int a[maxn], b[maxn], c[maxn];  // a[]是输入的序列,b[]是第一轮筛选出的数,c[]是第二轮即最后得出符合条件的数
     8 
     9 int main()
    10 {
    11     int i, j, k, l, n, v, temp, flag;
    12     while (scanf("%d", &n) != EOF)
    13     {
    14         for (i = 0; i < n; i++)
    15         {
    16             scanf("%d", &a[i]);
    17         }
    18         for (v = 31; v >= 0; v--)
    19         {
    20             temp = (1 << v) - 1;  // 关键所在,使得v-1~1位都置为1
    21         //  printf("tempout = %d\n", temp);
    22             flag = j = 0;
    23             for (i = 0; i < n; i++)
    24             {
    25                 if (a[i] & (1 << v))  // 挑出序列中满足第v位为1的数
    26                 {
    27             //      printf("a[%d] = %d\n", i, a[i]);
    28                     b[j++] = a[i];
    29             //      printf("b[%d] = %d\n", j-1, b[j-1]);
    30             //      printf("tempin1 = %d\n", temp);
    31                     temp &= a[i];
    32         //          printf("tempin2 = %d\n", temp);
    33                 }
    34             }
    35             if (j == 0)
    36                 continue;     // 没找到进行下一轮循环
    37         //  printf("j = %d\n", j);
    38         //  printf("temp_num = %d\n", temp);
    39             for (l = k = 0; k < j; k++)
    40             {
    41                 if (!(temp & b[k]))    // 验证第一轮筛选出的数中是否符合第v-1~1位与temp中相&后是否都为0
    42                 {
    43                     temp &= b[k];
    44                     c[l++] = b[k];
    45             //      printf("c[%d] = %d\n", l-1, c[l-1]);
    46                 }
    47             }
    48             if (l == 0)      // l 保存找到的总个数
    49                 continue;
    50             for (k = 0; k < l; k++)    // 找到一组解,且这个解满足是最优解
    51             {
    52                 if (k == 0)
    53                     printf("%d\n%d", l, c[k]);
    54                 else
    55                     printf(" %d", c[k]);
    56             }
    57             printf("\n");
    58             flag = 1;     // 找到符合条件的v的标志
    59             break;  
    60         }
    61         if (!flag)     // 没有找到
    62             printf("-1\n");
    63     }
    64     return 0;
    65 }

             

  • 相关阅读:
    vue 中 过滤filter 和 foreach的使用
    vuex 获取数据
    动态设置样式 calc计算
    vue-echarts-v3 使用 dataZoom属性 相关笔记
    访存加速-Speed-up of Memory Access Intensive Program
    台式机新添内存条无法开机?
    ADB的版本问题
    1184. Distance Between Bus Stops
    485. Max Consecutive Ones
    448. Find All Numbers Disappeared in an Array
  • 原文地址:https://www.cnblogs.com/windysai/p/3272191.html
Copyright © 2011-2022 走看看