题解 P2431 【正妹吃月饼】
假如做这道题想着用如下朴实的模拟,那肯定要WA至少4个点。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 typedef long long ll; 5 6 int main() { 7 ll a, b, sum = 0, ans = 0; 8 cin >> a >> b; 9 while(sum <= b) { 10 ans++; 11 sum = sum << 1 | 1; 12 } 13 cout << ans; 14 }
原因在于,数据大小。。。(2^63-1)
就比如说第二个点,输入数据如下:
140737488355336 140737488355456
能过才是奇迹。。。
那么显然我们应该使用位运算。
在这里先普及一下这玩意,尽管我觉得大家都会。。。
最基本的是左移和右移,分别是<<和>>。
他们具体的作用是将一个数的二进制位左移和右移。
然后有与或非亦或,即&,|,!,^
这几个很好理解,参考逻辑运算符就可以了。
知道了这下,那么新的思路就很明显了。
一位一位的看,如果是1就不管,如果是0就看改成1后符不符合题意。
最后再来统计1的数量。
程序如下:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 5 typedef long long ll; 6 7 int main() { 8 int ans = 0; 9 ll a, b; 10 cin >> a >> b; 11 while((a | (a + 1)) <= b) a |= a + 1; 12 while(a) { 13 ans += a & 1; 14 a >>= 1; 15 } 16 17 cout << ans; 18 }
【注意:long long一定要加!!!去掉了之后就只有80分了,两个点TLE!!】