当前位置:首页 > GESP > 【2023 GESP四级题解析】幸运数(洛谷B3850):解题思路与代码详解

【2023 GESP四级题解析】幸运数(洛谷B3850):解题思路与代码详解

4天前

【2023 GESP四级题解析】幸运数(洛谷B3850):解题思路与代码详解 GESP四级题 幸运数 洛谷B3850 位变换算法 模8判断 第1张

一、题目解读

2023年GESP四级题幸运数”(对应洛谷B3850)要求判断给定数字是否为“幸运数”。题目定义幸运数的规则为:将数字的奇数位(从右往左编号,个位为第1位)数字进行特定变换(乘以7后重复求和至数字≤9),最终所有数字位之和若为8的倍数,则该数为幸运数。例如,数字“12345”中奇数位为1和3,变换后求和判断是否为幸运数。题目需高效处理多组数据,考验位运算与数学变换能力。

二、解题思路

分步处理策略:

1. 位分离与变换:将数字转换为字符串,从末尾(个位)开始遍历,利用字符转数字获取每位值。

2. 奇数位处理:通过位置奇偶性判断,奇数位调用transformDigit函数进行“乘7-重复求和”变换,偶数位保持不变。

3. 求和与判断:累加变换后的各位数字,最终通过模8运算判定结果。

核心逻辑在于将复杂变换封装为独立函数,简化主流程,并利用字符串处理灵活遍历位序。

三、解题步骤解析

1. 输入处理:主函数接收测试用例数N,循环处理每组数字。

2. 转换奇数位:调用transformDigit对奇数位数字处理:

    乘7;

    循环拆解数字为各位和(如34→3+4=7),直至结果≤9。

3. 求和与判定:遍历数字字符串,奇数位应用变换结果,累加各位和,最后检查sum%8==0。

4. 输出结果:根据判定输出"T"或"F"。

四、代码与注释

#include <iostream>
#include <string>
using namespace std;

// 处理奇数位数字变换
int transformDigit(int digit) {
    digit *= 7;  // 先乘以7
    // 循环处理直到数字不大于9
    while (digit > 9) {
        int sum = 0;
        // 计算各位数字之和
        while (digit > 0) {
            sum += digit % 10;
            digit /= 10;
        }
        digit = sum;
    }
    return digit;
}

// 判断是否为幸运数
bool isLuckyNumber(long long num) {
    string s = to_string(num);
    int sum = 0;
    
    // 从个位开始(第1位),所以从字符串末尾开始处理
    for (int i = s.length() - 1, pos = 1; i >= 0; i--, pos++) {
        int digit = s[i] - '0';
        // 奇数位进行变换,偶数位保持不变
        if (pos % 2 == 1) {
            digit = transformDigit(digit);
        }
        sum += digit;
    }
    // 判断和是否是8的倍数
    return sum % 8 == 0;
}

int main() {
    int N;
    cin >> N;
    
    while (N--) {
        long long num;
        cin >> num;
        if (isLuckyNumber(num)) {
            cout << "T" << endl;
        } else {
            cout << "F" << endl;
        }
    }
    
    return 0;
}


五、总结

本文解析的GESP四级题“幸运数”解法,通过以下关键点实现高效求解:

1. 位序与奇偶性判断:利用字符串逆序遍历自然对应奇数位;

2. 数学变换封装:将“乘7-拆位求和”抽象为独立函数,提升代码可读性;

3. 模运算优化:直接求和后模8判断,避免中间结果溢出。

该解法兼顾算法逻辑与代码简洁性,适合竞赛与算法学习参考。


原创内容 转载请注明出处

分享给朋友:

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。