• Neko Performs Cat Furrier Transform CodeForces


    Neko Performs Cat Furrier TransformCodeForces - 1152B   

      题目大意:给你一个x,在40步操作以内把x变成2m1,m为非负整数。对于每步操作,奇数步可以在(0<=n<=30)中挑选一个n,将x(2n1),而偶数步将x++。输出操作步数,以及在每个奇数步异或的n,多个答案,输出任一答案,保证至少有一个答案。

      一开始傻逼了,真的照题意所说的去写了一个深搜,果断超时了。其实每个奇数步也是异或一个二进制全1的数,那我们就直接把x尾部连续0部分,全部异或为1,那么在偶数步加1的话,又会往前进位填补前面的0(如果有的话0),然后再继续把x尾部连续0部分,全部异或为1,直到x为二进制全1即可。

      就比如x=80,二进制为1010000,我们第一步先异或个24-1=15即1111,x就变成了95=1011111,然后第二步x++,x就成了96=1100000,第三步在异或个25-1=31即11111,x变成了127=1111111,结束。

      因为1e6,最多就220左右,肯定不会超出40步。而取得末尾连续0部分正是树状数组里的那个x&(-x),不懂的可以去了解下。

     1 #include<cstdio>
     2 #include<vector>
     3 #include<cmath>
     4 #include<map>
     5 using namespace std;
     6 map<int,int> m;
     7 vector<int> ans;
     8 int main()
     9 {
    10     int cf2=1;
    11     //把终止情况,2^i-1标记一下
    12     m[0]=1; 
    13     for(int i=1;i<=30;i++)
    14     {
    15         cf2<<=1;
    16         m[cf2-1]=1;
    17     }
    18     int x,step=0;
    19     scanf("%d",&x);
    20     while(!m[x])
    21     {
    22         step++;
    23         if(step&1)
    24         {
    25             int y=x&(-x),n=0;
    26             x^=(y-1);
    27             while(y)
    28             {
    29                 n++;
    30                 y>>=1; 
    31             }
    32             //y=2^(n-1) 
    33             ans.push_back(n-1);  
    34         }
    35         else
    36             x++;
    37     }
    38     printf("%d
    ",step);
    39     for(int i=0;i<ans.size();i++)
    40     {
    41         if(i)
    42             putchar(' ');
    43         printf("%d",ans[i]);
    44     } 
    45     printf("
    ");
    46     return 0;
    47 }
    慢慢来不急
  • 相关阅读:
    (CodeForces 548B 暴力) Mike and Fun
    (BestCoder Round #64 (div.2))Array
    (2015 杭电校赛 )玩骰子
    js基础
    frame框架标签
    html
    div嵌套div标签 里层的div透明属性
    div嵌套div标签
    盒子标签div嵌套
    divspan盒子模型
  • 原文地址:https://www.cnblogs.com/LMCC1108/p/10768353.html
Copyright © 2020-2023  润新知