B4357 [GESP202506 二级] 幂和数

题目描述

对于正整数 $n$,如果 $n$ 可以表为两个 $2$ 的次幂之和,即 $n = 2^x + 2^y$($x, y$ 均为非负整数),那么称 $n$ 为幂和数。

给定正整数 $l, r$,请你求出满足 $l \leq n \leq r$ 的整数 $n$ 中有多少个幂和数。

输入格式

一行,两个正整数 $l, r$,含义如上。

输出格式

输出一行,一个整数,表示 $l, r$ 之间幂和数的数量。

输入输出样例 #1

输入 #1

2 8

输出 #1

6

输入输出样例 #2

输入 #2

10 100

输出 #2

20

说明/提示

对于所有测试点,保证1≤l≤r≤10 4。

题目要求我们找出在 l≤n≤r 区间内的幂和数,那么我们可以遍历这个区间中的每一个整数 i,然后判断 i 是否为一个幂和数。

如何判断一个数 i 是不是幂和数呢?根据定义,我们需要检查是否存在非负整数 x,y 使得 2
x
+2
y
=i。因此,我们可以再次使用枚举法,枚举所有可能的 x 和 y 的组合,计算出 2
x
+2
y
的值,并与当前的数 i 进行比较。计算 2
x
,可以使用 pow 函数,即 pow(2.0, x) 完成。

那么 x 和 y 的枚举范围是多少呢?由于题目中 r 的最大值为 10
4
,而 2
13
=8192,2
14
=16384,所以 2
x
和 2
y
都不可能超过 10
4
。这意味着 x 和 y 的取值范围不会超过 14。我们可以安全地将 x 和 y 的枚举范围设定为 0 到 14。如果让 x,y 的枚举范围大很多(比如说枚举到 n),那么 pow(2.0, x),pow(2.0, y) 的结果就会超过 int 类型能容纳的范围而产生错误\

#include <iostream>
using namespace std;
int main()
{
	int l,r,a,b,n,cnt = 0;
	cin>>l>>r;
	a=1;
	while(a<=r)
	{
		b=a;
		while(b<=r)
		{
			n=a+b;
			if(n>=l&&n<=r) cnt++;
			b*=2;
		}
		a*=2;
	}
	cout<<cnt;
	return 0;
}