牛客网-2018 美团 CodeM 编程大赛-初赛 B 轮-3-低位值

ACM模版

描述

题解

一个规律题。默认, l l 0 ,考虑取 r r ,首先,如果有非最高位 1 存在 x x 个,有第二个部分公式得答案加上 x ,然后根据第三个公式得答案加 1 1 并且获取一个新的二进制串 r (全是 1 1 ),以此类推,直到 r = 0

对于 r r 我们需要考虑两种情况,因为上述循环的第一次取的 r 不一定全是 1 1 。如果 n 二进制存在至少两个一,例如 100100110 100100110 … ,那么从高位开始查找到第二个 1 1 ,假如说第一个 1 的权值是 2k 2 k ,第二个 1 1 的权值是 2 k ,然后取 r r 2 k + 2 k 1 ,此时二进制是 100011111 100011111 … ,也就是说初始存在 x=k x = k 个非最高位 1 1 ,这是第一种情况;我们还需要考虑一下 r n n 的情况,计数有多少个非最高位 1 ,然后在这两种情况中取最优。这样我们就处理完第一轮的运算了,后续的类推,都保证是全 1 1 二进制,所以我们可以通过预处理来确定不同长度的全 1 二进制通过多少次运算可以得到 r=0 r = 0 的状态。

这个题仔细模拟一下,很容易找到规律的,一开始以为是数论题,着实有些虚。

代码

#include <iostream>
#include <string>

using namespace std;

const int MAXN = 2e4 + 10;

string num;
long long temp[MAXN] = {
  0, 1, 1};

void init()
{
    for (int i = 3; i < MAXN; i++)
    {
        temp[i] = temp[i - 1] + i - 1;
    }
}

int main(int argc, const char * argv[])
{
    init();

    cin >> num;

    long long ans = 0;
    for (int i = 1; i < num.length(); i++)
    {
        if (num[i] == '1')
        {
            ans = (num.length() - 1) - i;
            break;
        }
    }

    long long cnt = 0;
    for (int i = 1; i < num.length(); i++)
    {
        if (num[i] == '1')
        {
            cnt++;
        }
    }

    ans = max(ans, cnt);
    ans += temp[num.length()];

    cout << ans << '\n';

    return 0;
}
全部评论

相关推荐

01-14 12:08
门头沟学院 Java
神哥了不得:(非引流)1.既然发出来了简历,就稍微提一点点小建议,确实简历很不错了,练手项目可以换一些质量高的,工作内容,可以加上一些量化指标,比如第一条系统响应速度由多少变成多少,减少了百分之多少,第4条就很不错。2.广投,年前实习招募比较少了
点赞 评论 收藏
分享
神哥了不得:放平心态,再找找看吧,主要现在计算机也变卷了,然后就比较看学历了,之前高中毕业你技术强,都能找到工作的
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务