CCF-CSP第41次认证第一题——平衡数

题目描述

小 P 在学习了位运算后,定义了如下"平衡数":

  • 对于一个正整数 aa,如果其二进制表示中 10 的个数相等,则称其为平衡数。

这里的二进制表示以 1 为最高位,即不考虑更高位用于补位的 0。例如,正整数 12 的二进制表示为 1100,包含两个 1 和两个 0。在实际存储中,更高位可能需要填 0 补位,如 00001100,在本题中无需考虑此种情况。

小 P 已经生成好了 n 个正整数 a1,a2,⋯,an​,试编程统计里面有多少个平衡数。

输入格式

从标准输入读入数据。

输入的第一行包含一个正整数 n,第二行包含空格分隔的 n 个正整数 a1,a2,⋯,an​。

输出格式

输出到标准输出。

输出一个整数,表示 a1,a2,⋯,an中平衡数的个数。

样例输入

复制代码
3
2 5 9

样例输出

复制代码
2

样例解释

2 的二进制表示为 10,是平衡数;

5 的二进制表示为 101,不是平衡数;

9 的二进制表示为 1001,是平衡数。

子任务

50% 的测试点满足:0<ai≤256;

全部的测试点满足:0<n≤100 且 0<ai≤109。

题解

判断数字是否为平衡数的方法:首先将数字转换为二进制,然后统计其中0和1的个数是否相等。以下是具体实现方案:

二进制转换方法

将十进制数转换为二进制数的步骤如下:

  1. 对原数进行模2运算
  2. 将结果从低位到高位依次记录
  3. 将所得数值倒序排列即为对应的二进制数

在实际操作中,我们无需获取完整的二进制表示,只需统计位数即可。这里使用临时变量temp:

  • 当模2结果为1时加1
  • 否则减1
  • 最终判断temp是否为0

位运算优化方案

采用异或(XOR)运算进行优化,通过五轮"对折"异或将32位整数的所有位信息压缩到最低位:

步骤 操作 效果
1 x ^= x >> 16 高16位与低16位异或 → 结果在低16位
2 x ^= x >> 8 高8位与低8位异或 → 结果在低8位
3 x ^= x >> 4 高4位与低4位异或 → 结果在低4位
4 x ^= x >> 2 高2位与低2位异或 → 结果在低2位
5 x ^= x >> 1 高1位与低1位异或 → 结果在最低位

最终通过!(x & 1)判断原始数字中1的个数是否为偶数。

示例演示

x = 13为例(二进制:1101,3个1):

复制代码
初始:  x = 0000 0000 0000 0000 0000 0000 0000 1101
第1轮: x ^ (x >> 16) → x不变
第2轮: x ^ (x >> 8) → x不变
第3轮: x ^ (x >> 4) → x不变
第4轮: x ^ (x >> 2) → x = ...0000 1110 (14)
第5轮: x ^ (x >> 1) → x = ...0000 1001 (9)
最终: !(x & 1) = false

代码如下

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

int cnt,n,op;

bool check(int x){
    int temp=0;
    while(x){
        if(x%2)temp++;
        else temp--;
        x/=2;
    }
    return temp==0;
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>op;
        if(check(op))cnt++;
    }
    cout<<cnt;
}

给一个位运算优化的方法

cpp 复制代码
#include<bits/stdc++.h>

using namespace std;

int cnt,n,op;

bool check(int x){
    cout<<sizeof(x)<<endl;  
    x=x^x>>16;
    x=x^x>>8;
    x=x^x>>4;
    x=x^x>>2;
    x=x^x>>1;
    return !(x&1);
}

int main(){
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>op;
        if(check(op))cnt++;
    }
    cout<<cnt;
}
相关推荐
Book思议-2 小时前
【数据结构实战】栈的经典应用:后缀表达式求值 +中缀转后缀 ,原理 + 代码双通透
数据结构·算法··后缀表达式·后缀转中缀
炽烈小老头2 小时前
【 每天学习一点算法 2026/03/30】跳跃游戏
学习·算法
水饺编程2 小时前
第4章,[标签 Win32] :SysMets3 程序讲解01
c语言·c++·windows·visual studio
wuweijianlove2 小时前
算法性能预测的统计模型与参数敏感性分析的技术6
算法
Just right2 小时前
重学算法 数组 LC27移除元素
数据结构·算法
郝学胜-神的一滴2 小时前
巧解括号序列分解问题:栈思想的轻量实现
开发语言·数据结构·c++·算法·面试
代码改善世界2 小时前
【C++初阶】string类(一):从基础到实战
开发语言·c++
计算机安禾2 小时前
【数据结构与算法】第15篇:队列(二):链式队列的实现与应用
c语言·开发语言·数据结构·c++·学习·算法·visual studio
迷途之人不知返3 小时前
初次学习模板
c++