逐位统计每个正整数二进制表示中的 0 和 1,数量相等时计数。
OJ: shumeng
题目 ID: CSP202603A
难度:未知
标签:位运算枚举计数
日期: 2026-07-31 16:22
形式化题目
给定 1 与 0 的个数相等。这里二进制表示以最高位的 1 为起点,不考虑更高位补位的 0。统计
思路
统计一个数的二进制位
不断取出当前数的最低位:最低位为 1 就累加 ones,否则累加 zeros,然后右移一位。循环结束时恰好统计了从最高位 1 开始的所有二进制位。
关键点在于循环条件是 x > 0:一旦 x 变成 0,就说明已经到达最高位,更高位那些补位的 0 不会被统计进去。
判断与计数
对每个数调用一次统计过程,ones == zeros 时答案加一。
代码
cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-31 16:22
* update_at: 2026-08-17 22:40
*/
#include <bits/stdc++.h>
using namespace std;
// 判断正整数 x 的二进制表示中 1 和 0 的个数是否相等。
bool is_balanced(unsigned int x) {
int ones = 0; // 二进制中 1 的个数
int zeros = 0; // 二进制中 0 的个数
while (x > 0) {
if (x & 1U) {
ones++;
} else {
zeros++;
}
x >>= 1;
}
return ones == zeros;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
int answer = 0;
for (int i = 0; i < n; i++) {
unsigned int value;
cin >> value;
if (is_balanced(value)) {
answer++;
}
}
cout << answer << '\n';
return 0;
}复杂度
设第
- 时间:每个数只扫描自己的二进制位,总时间复杂度为
。 - 空间:只用常数个变量,空间复杂度为
。
总结
统计二进制位时从数值本身开始右移,就自然跳过了表示中的高位补零。这类逐位处理可以直接用位移和取最低位完成,不需要先把数转成字符串。