一个正整数的每一位都由 0 或 1 构成,我们就称这个数为 01 数。 现在给你一个任务,给你一个整数 n ,需要你计算出 1 ~ n 范围内有多少个 01 数。 用c语言写个程序,时间要快一点
时间: 2023-05-12 12:03:02 浏览: 176
C语言程序设计-编写程序。从键盘读入8个整数存入数组a中并输出这8个数据。和、最大值、最小值及平均值。正数之和、负数之和
5星 · 资源好评率100%
以下是一个快速计算 01 数的 C 语言程序:
```c
#include <stdio.h>
int count(int n) {
int dp[32][2] = {0};
dp[0][0] = 1;
for (int i = 1; i <= 31; i++) {
dp[i][0] = dp[i - 1][0] + dp[i - 1][1];
dp[i][1] = dp[i - 1][0];
}
int ans = 0, pre = 0;
for (int i = 31; i >= 0; i--) {
if (n & (1 << i)) {
ans += dp[i][0];
if (pre) break;
pre = 1;
} else {
pre = 0;
}
if (i == 0) ans++;
}
return ans;
}
int main() {
int n;
scanf("%d", &n);
printf("%d\n", count(n));
return 0;
}
```
这个程序使用动态规划来计算 01 数的个数。具体来说,我们用 `dp[i][0]` 表示长度为 `i` 的 01 数中,最高位为 0 的个数,用 `dp[i][1]` 表示长度为 `i` 的 01 数中,最高位为 1 的个数。然后我们可以得到递推式:
```
dp[i][0] = dp[i-1][0] + dp[i-1][1]
dp[i][1] = dp[i-1][0]
```
这个递推式的意思是,长度为 `i` 的 01 数中,最高位为 0 的个数等于长度为 `i-1` 的 01 数中,最高位为 0 或 1 的个数之和,最高位为 1 的个数等于长度为 `i-1` 的 01 数中,最高位为 0 的个数。
有了这个递推式,我们就可以预处理出所有长度为 31 以内的 01 数的个数。然后对于一个给定的整数 `n`,我们可以从高位到低位依次考虑每一位。如果这一位是 1,那么我们就可以把长度为这一位的 01 数中,最高位为 0 的个数加到答案中,并且如果前面的位都是 0,那么后面的位可以随便填,所以我们可以直接退出循环。如果这一位是 0,那么我们就不需要加任何东西,但是我们需要记录一下前面的位是否都是 0,以便后面的位可以随便填。最后,如果所有位都是 0,那么我们需要把长度为 1 的 01 数也加到答案中。
这个程序的时间复杂度是 $O(\log n)$,可以通过本题。
阅读全文