GESP认证C++编程真题解析 | B14074 [GESP202509 五级] 有趣的数字和

欢迎大家订阅我的CSDN专栏算法题解:C++与Python实现
本专栏旨在帮助大家从基础到进阶 ,逐步提升编程能力,助力信息学竞赛备战!

专栏特色
1.经典算法练习:根据信息学竞赛大纲,精心挑选经典算法题目,提供清晰的代码实现与详细指导,帮助您夯实算法基础。
2.系统化学习路径:按照算法类别和难度分级,从基础到进阶,循序渐进,帮助您全面提升编程能力与算法思维。

适合人群:

  • 准备参加蓝桥杯、GESP、CSP-J、CSP-S等信息学竞赛的学生
  • 希望系统学习C++/Python编程的初学者
  • 想要提升算法与编程能力的编程爱好者

附上汇总帖:GESP认证C++编程真题解析 | 汇总


【题目来源】

洛谷:[P14074 GESP202509 五级] 有趣的数字和 - 洛谷

【题目描述】

如果一个正整数的二进制表示包含奇数个 $1$,那么小 A 就会认为这个正整数是有趣的。

例如,$7$ 的二进制表示为 $(111)_2$,包含 $1$ 的个数为 $3$ 个,所以 $7$ 是有趣的。但是 $9=(1001)_2$ 包含 $2$ 个 $1$,所以 $9$ 不是有趣的。

给定正整数 $l,r$,请你统计满足 $l≤n≤r$ 的有趣的整数 $n$ 之和。

【输入】

一行,两个正整数 $l,r$,表示给定的正整数。

【输出】

一行,一个正整数,表示 $l,r$ 之间有趣的整数之和。

【输入样例】

3 8

【输出样例】

19

【算法标签】

《洛谷 P14074 有趣的数字和》 #GESP# #2025#

【代码详解】

#include <bits/stdc++.h>
using namespace std;

#define int long long  // 使用长整型防止溢出

int l, r;              // 输入的数字区间[l, r]
int ans;               // 存储计算结果
int b;                 // 计算第b个区间
int v[9] = {0, 1, 3, 3, 7, 7, 7, 14, 22};  // 预计算的小数值结果(1-8的答案)

/**
 * 计算数字x的二进制表示中1的个数(汉明重量)
 * @param x 要计算的数字
 * @return 二进制中1的个数
 */
int check(int x)
{
    int cnt = 0;  // 计数器,记录1的个数
    while (x > 0)
    {
        if (x & 1)  // 检查最低位是否为1
            cnt++;   // 如果是1,计数器加1
        x = x >> 1;  // 右移一位,相当于除以2
    }
    return cnt;
}

/**
 * 计算从1到x的所有满足条件的数的和
 * @param x 上界
 * @return 计算结果
 */
int f(int x)
{
    // 如果x小于等于8,直接返回预计算的结果
    if (x <= 8)
        return v[x];
    
    // 计算区间个数(默认向下取整)
    b = x / 4;
    
    // 计算从第1到第b个区间的总和
    ans = (b * b) * 4 - b;
    
    // 计算剩余部分的值(从b*4到x)
    for (int i = (b * 4); i <= x; i++)
    {
        // 如果二进制1的个数为奇数,则累加
        if (check(i) % 2)
            ans += i;
    }
    
    return ans;
}

signed main()
{
    // 输入区间范围
    cin >> l >> r;
    
    // 输出区间内满足条件的数的和(前缀和思想)
    cout << f(r) - f(l - 1);
    
    return 0;
}

【运行结果】

3 8
19
posted @ 2026-01-14 15:09  热爱编程的通信人  阅读(2)  评论(0)    收藏  举报