• codeforces Good Bye 2015 B. New Year and Old Property


    题目链接:http://codeforces.com/problemset/problem/611/B

    题目意思:就是在 [a, b] 这个范围内(1 ≤ a ≤ b ≤ 10^18)统计出符合二进制数表示只有 1 个 0 的数量是多少。

      ***********************

      首先贴出一段绝对会超时的代码,连提交的勇气都木有呢~因为第四组数据已经接近龟速了,所以。。。(大家可忽略)

      

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 typedef __int64 ll;
     8 ll a, b;
     9 ll ans;
    10 
    11 int main()
    12 {
    13     #ifndef ONLINE_JUDGE
    14         freopen("in.txt", "r", stdin);
    15     #endif // ONLINE_JUDGE
    16 
    17     while (scanf("%I64d%I64d", &a, &b) != EOF) {
    18         __int64 i;
    19         ans = 0;
    20 
    21         for (i = a; i <= b; i++) {
    22            __int64 l = i;
    23            int c = 0;
    24            while (l && c <= 1) {
    25                c += ((l & 1) == 0 ? 1 : 0);
    26                l >>= 1;
    27           }
    28           if (c == 1)
    29             ans++;
    30 
    31         }
    32         printf("%I64d
    ", ans);
    33     }
    34     return 0;
    35 }

      ***********************

      

      讲讲正确的解题思路 —— 就是暴力枚举啦.......当然不是将十进制数先化成二进制数再慢慢比对啦,我上面的代码就类似这个思想了,讲多都是泪,呜呜呜~~~

      是模拟二进制数,在 [1, 10^18] 范围内,统计出只出现二进制表示0只出现1次的数

      我还是第一次知道原来可以这样算= =、、、 慢慢积累经验吧~~~

      另外讲一讲数的范围, 2^61 已经比 10^18要大了,所以枚举的时候,举例到61次就行,代码有详尽的注释,大家慢慢欣赏 ^_^

      

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 typedef __int64 ll;
     8 const int bit = 61;  // 2^61 = 1,152,921,504,606,846,976 
     9 
    10 int main()
    11 {
    12     #ifndef ONLINE_JUDGE
    13         freopen("in.txt", "r", stdin);
    14     #endif // ONLINE_JUDGE
    15 
    16     ll a, b;
    17     while (scanf("%I64d%I64d", &a, &b) != EOF) {
    18         int ans = 0;
    19 
    20         for (int i = 2; i <= bit; i++) {
    21             ll mea = (1ll << i) - 1;   // 1, 11, 111, 1111, ...
    22 
    23             for (int j = 0; j < i-1; j++) {
    24                 ll t = mea - (1ll << j); // (1ll<<j): 1, 10, 100, 1000, ...
    25                 ans += (t >= a && t <= b);
    26             }
    27         }
    28         printf("%d
    ", ans);
    29     }
    30     return 0;
    31 }

      

      

  • 相关阅读:
    [bzoj4197][Noi2015]寿司晚宴
    [bzoj3531][Sdoi2014]旅行
    [洛谷P1430]序列取数
    [洛谷P2044][NOI2012]随机数生成器
    [洛谷P2839][国家集训队]middle
    [洛谷P3937]Changing
    [bzoj3532][Sdoi2014]Lis
    [洛谷P2590][ZJOI2008]树的统计
    [洛谷P4311]士兵占领
    [洛谷P1879][USACO06NOV]玉米田Corn Fields
  • 原文地址:https://www.cnblogs.com/windysai/p/5093963.html
Copyright © 2020-2023  润新知