【2024GXOI进阶】数字谜题(number)

解题思路

  1. 问题分析:题目要求将给定的十进制数转换为二进制后,找出其中最长的连续1的个数。

  2. 关键步骤

    • 将十进制数转换为二进制表示(不需要实际存储二进制字符串,可以通过数学方法处理)

    • 遍历二进制位,统计连续1的长度

    • 记录并更新最大连续1的长度

  3. 优化考虑

    • 直接对数字进行除2操作,通过余数判断当前位是否为1

    • 使用循环处理每一位,避免转换为字符串的开销

    • 使用两个变量分别记录当前连续1的个数和最大连续1的个数

#include<bits/stdc++.h>
#define ll long long  // 定义long long类型简写为ll
using namespace std;

// 解决问题的函数,输入一个十进制数n,返回其二进制表示中最长连续1的个数
ll solve(ll n)
{
    ll res = 0, sum = 0;  // res记录最大连续1个数,sum记录当前连续1个数
    
    while(n != 0)  // 当n不为0时循环处理每一位
    {
        if(n % 2 == 1)  // 如果当前位是1(通过n%2判断)
            sum++;       // 当前连续1的个数加1
        else {           // 如果当前位是0
            res = max(res, sum);  // 更新最大连续1个数
            sum = 0;     // 重置当前连续1计数器
        }
        n /= 2;          // 相当于右移一位,处理下一位
    }
    
    res = max(res, sum); // 循环结束后再次检查,防止最长连续1在最高位
    return res;          // 返回最终结果
}

int main()
{
    int t; cin >> t;     // 读取测试用例数量
    while(t--)           // 处理每个测试用例
    {
        ll n; cin >> n;  // 读取十进制数字
        cout << solve(n) << endl;  // 调用solve函数并输出结果
    }
    return 0;
}

代码执行流程

  1. 读取测试用例数量T

  2. 对于每个测试用例:

    • 读取十进制数字n

    • 调用solve函数处理n:

      • 初始化res和sum为0

      • 通过循环不断除以2,检查余数判断当前位是否为1

      • 如果是1则增加sum,否则更新res并重置sum

      • 最后再次检查res和sum的关系

    • 输出solve函数返回的结果

这种方法高效地利用了数学运算避免了转换为二进制字符串的开销,适合处理大数和大规模测试用例。

posted @ 2025-05-08 21:26  CRt0729  阅读(59)  评论(0)    收藏  举报