L2-029 特立独行的幸福

本文介绍了一种筛选特定类型幸福数的方法,通过遍历指定区间内的每个数,并使用迭代和标记策略来确定哪些数属于特立独行的幸福数。文中详细解释了算法流程,并提供了完整的AC代码实现。
题目大意

在这里插入图片描述

算法思路

首先我们从小到大遍历区间内的每一个数,对于区间内的一个数t,我们将t迭代,同时用一个vector存下迭代的每一个数,同时进行标记,当t为1或者t在vector中重复出现时,停止遍历,如果t为1,则记录t的独立性(t是幸福数但t未必是特立独行的幸福数)。
遍历完数组后,我们只需要遍历之前记录过的幸福数即可,如果当前数没有依附于其他幸福数,也就是没有被数组标记过,也就是特立独行的幸福数,则输出

AC代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <sstream>
using namespace std;

const int N = 10010;
map<int, int> d;
int n, m;
bool st[N];

int f(int x)
{
    int sum = 0;
    while(x)
    {
        sum += (x % 10) * (x % 10);
        x /= 10;
    }
    return sum;
}

bool prime(int x)
{
    if(x == 1) return false;
    for(int i = 2; i <= x / i; i++)
    {
        if(x % i == 0) return false;
    }
    return true;
}

int main(void)
{
    cin >> n >> m;
    for(int i = n; i <= m; i++)
    {
        int t = i;
        vector<int> member;
        while(t != 1)
        {
            t = f(t);
            if(find(member.begin(), member.end(), t) != member.end()) break;
            st[t] = true;
            member.push_back(t);
        }
        if(t == 1)
        {
            if(prime(i)) d[i] = member.size() * 2;
            else d[i] = member.size();
        }
    }

    int cnt = 0;
    for(auto i : d)
    {
        if(!st[i.first])
        {
            cout << i.first << ' ' << i.second << endl;
            cnt++;
        }
    }
    if(!cnt) puts("SAD");
    return 0;
}
7-6 特立独行幸福 (25分) 对一个十进制的各位字做一次平方和,称作一次迭代。如果一个十进制能通过若干次迭代得到 1,就称该幸福。1 是一个幸福。此外,例如 19 经过 1 次迭代得到 822 次迭代后得到 68,3 次迭代后得到 100,最后得到 1。则 19 就是幸福。显然,在一个幸福迭代到 1 的过程中经过的字都是幸福,它们的幸福是依附于初始字的。例如 82、68、100 的幸福是依附于 19 的。而一个特立独行幸福,是在一个有限的区间内不依附于任何其它字的;其独立性就是依附于它的的幸福的个。如果这个还是个素,则其独立性加倍。例如 19 在区间[1, 100] 内就是一个特立独行幸福,其独立性为 2×4=8。 另一方面,如果一个大于1的字经过次迭代后进入了死循环,那这个就不幸福。例如 29 迭代得到 85、89、145、4220、4、16、37、58、89、…… 可见 89 到 58 形成了死循环,所以 29 就不幸福。 本题就要求你编写程序,列出给定区间内的所有特立独行幸福和它的独立性。 输入格式: 输入在第一行给出闭区间的两个端点:1<A<B≤10 ​4 ​​ 。 输出格式: 按递增顺序列出给定闭区间 [A,B] 内的所有特立独行幸福和它的独立性。每对字占一行,字间以 1 个空格分隔。 如果区间内没有幸福,则在一行中输出 SAD。 输入样例 1: 10 40 输出样例 1: 19 8 23 6 28 3 31 4 32 3 注意:样例中,10、13 也都是幸福,但它们分别依附于其他字(如 23、31 等等),所以不输出。其它字虽然其实也依附于其它幸福,但因为那些字不在给定区间 [10, 40] 内,所以它们在给定区间内是特立独行幸福。 输入样例 2: 110 120 输出样例 2: SAD
### 关于L2-029 特立独行幸福问题的解决方案 对于题目 **L2-029 特立独行幸福**,其核心在于模拟一个区间内的值变化过程,并统计满足特定条件的结果量。以下是基于C++的一种实现方式。 #### 题目分析 此题的关键点包括: 1. 输入两个正整 \(N\) 和 \(M\),分别表示功能模块的量以及测试输入序列的量。 2. 对于每一个测试输入序列,计算并判断是否落在指定范围内 \([A, B]\),同时记录符合条件的状态次。 3. 输出最终状态的变化情况及其对应的幸福感值。 需要注意的是,在处理过程中可能会遇到较大的据量或者边界条件异常的情况[^5]。因此,程序设计时应充分考虑到这些潜在的风险因素。 #### 代码实现 下面提供了一个完整的C++版本解答: ```cpp #include <iostream> #include <vector> using namespace std; // 定义最大可能的据规模 const int MAX_N = 1e4; const int MAX_M = 1e2; int main(){ int N, M; // 功能模块目 & 测试用例目 cin >> N >> M; vector<int> modules(N); for(auto &module : modules){ cin >> module; } long long A, B; cin >> A >> B; bool flag = false; int count = 0; while(M--){ char op; int value; cin >> op >> value; switch(op){ case '+': { for(auto &m : modules)m += value; break; } case '-': { for(auto &m : modules)m -= value; break; } case '*': { for(auto &m : modules)m *= value; break; } case '/': { if(value != 0){ for(auto &m : modules)m /= value; } else{ cout << "Error: Division by zero." << endl; return -1; } break; } } // 统计当前状态下处于[A,B]区间的元素个 int currentCount = 0; for(const auto &m : modules){ if(m >= A && m <= B)currentCount++; } if(currentCount > count){ count = currentCount; flag = true; } } if(flag){ cout << count << endl; } else{ cout << "-1" << endl; } return 0; } ``` 上述代码通过读取初始的功能模块列表和一系列操作指令来动态调整各模块的值,并实时监控它们是否位于给定范围之内。如果存在至少一次有效更新,则输出最高达到的有效覆盖度;反之则返回 `-1` 表明没有任何时刻符合要求。 #### 注意事项 在实际编码调试阶段发现了一些容易忽略的地方,比如组越界访问可能导致未预期的行为却不易察觉等问题。所以建议开发者们务必重视单元测试环节,尤其是针对极端情形下的鲁棒性验证。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值