GESP 2026年3月C++三级(二进制回文串)

202603-1 二进制回文串

题目描述

对于一个正整数 nnn,我们将其转换为不含前导零的二进制表示,如果这个二进制序列从左向右读与从右向左读完全相同,则称该数为二进制回文数。例如,999 的二进制表示为 (1001)2(1001)_2(1001)2,是二进制回文数;121212 的二进制表示为 (1100)2(1100)_2(1100)2,不是二进制回文数。

你的任务是:给定一个正整数 nnn,计算在 111 到 nnn 的范围内二进制回文数的数量。

输入格式

输入一行,包含一个正整数 nnn。

输出格式

输出一行,包含一个数,表示在 111 到 nnn 的范围内二进制回文数的数量。

样例输入 1

复制代码
15

样例输出 1

复制代码
6

提示

【样例解释】

样例 1 中,111 到 151515 范围内 111、333、555、777、999、151515 是二进制回文数。

【数据范围】

1≤n≤1051 \leq n \leq 10^51≤n≤105

解题思路

方法:数位翻转比较法

直接遍历 111 到 nnn 的每个数,将其二进制表示从低位到高位依次取出并重新组合成一个新的数 mmm,如果 mmm 与原数相等,则说明该数的二进制表示是回文的。

核心思想:

  • 将原数的二进制位从低到高依次取出(j%2j\%2j%2)
  • 同时将取出的位按从左到右的顺序重新组合(m=m∗2+j%2m = m*2 + j\%2m=m∗2+j%2)
  • 最终 mmm 就是原数二进制表示的翻转,若 m==im==im==i,则为回文数

代码解析

cpp 复制代码
#include <bits/stdc++.h>
using namespace std;

int main() {
    int n, cnt = 0;
    cin >> n;
    
    // 遍历1到n的所有数
    for (int i = 1; i <= n; i++) {
        int j = i, m = 0;
        
        // 将i的二进制位从低到高取出,同时构建翻转后的数m
        while (j) {
            m = m * 2 + j % 2;  // 取出最低位,添加到m的最高位
            j /= 2;             // 移除最低位
        }
        
        // 如果翻转后的数等于原数,说明是二进制回文数
        if (m == i) cnt++;
    }
    
    cout << cnt;
    return 0;
}

样例验证

数字 二进制表示 翻转后的值 是否回文
1 1 1
2 10 01=1
3 11 11
4 100 001=1
5 101 101
6 110 011=3
7 111 111
8 1000 0001=1
9 1001 1001
10 1010 0101=5
11 1011 1101=13
12 1100 0011=3
13 1101 1011=11
14 1110 0111=7
15 1111 1111

结果:共6个二进制回文数(1、3、5、7、9、15)


相关推荐
罗西的思考11 小时前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队14 小时前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
用户8055336980321 小时前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
To_OC1 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC1 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK1 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境2 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
_清歌2 天前
DSpark 深度解读:DeepSeek-V4 如何用「半自回归」把推理速度提升 85%
算法
统计实现局2 天前
SVD 的三步走:双对角化、Givens 收敛、排序
算法