题目链接: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 }