题解 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!!】

posted @ 2018-10-19 21:46  Ilverene  阅读(153)  评论(0编辑  收藏  举报