【L2-029 特立独行的幸福】

天梯赛L2-029 特立独行的幸福

题目详情:

在这里插入图片描述
在这里插入图片描述
输入样例 1:

10 40

输出样例 1:

19 8
23 6
28 3
31 4
32 3

在这里插入图片描述
在这里插入图片描述

思路:

这个题也是借鉴了网上大佬的写法
这个题是求特立独行的幸福数和它的独立性,因为每个区间有很多幸福数,所以题目中给出了依附的定义。
我暂且把幸福数经过迭代变成1的过程中出现的数叫做过程数。
这个题就是说从A到B的过程中,每个数肯定都要经历一次判断,而且这个数不是幸福数就是循环数,首先肯定是要先求它的过程数(写一个函数),注意这里求的是区间内的过程数接下来就是循环一遍所有的数而且每个数都要进行一次迭代求它的过程数:
先判断过程数是不是1?
如果不是1,再判断是不是循环数,如何再存入v容器中。
那么第一种情况<如果是循环数呢>:那么v容器中肯定<先存入了第一次出现的数>,
所以<利用find函数>判断这个数是否在v容器中出现过<如果出现过>就证明它是循环数,直接进行下一次循环。
如果是幸福数呢:那么在过程数等于1的时候,首先把<这个等于1的过程数的初始数>标记为特立独行的幸福数。
而等于1之前肯定还是会有过程数存入v容器中,那么就将<这些过程数>都标记为不是特立独行的幸福数,并且<这些过程数>都是<依附于初始数的>
所以这个时候v容器的大小+1就是独立性的大小
如果这里看不懂没关系,结合代码去看就好啦。

详细代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 5;
int happynum(int u)//十进制数的各位数字做一次平方和
{
    int sum = 0;
    while(u)
    {
        int a = u%10;
        sum += a*a;
        u = u/10;
    }
    return sum;
}
bool isprime(int u)//判断素数
{
    for(int i=2; i<sqrt(u); i++)
    {
        if(u % i == 0)
            return false;
    }
    return true;
}
int visit[maxn];//特立独行幸福数为1,不特立独行幸福数为-1
int a,b;
vector<int>v;//存放依附于初始数字的幸福数
int num[maxn];//独立数
int main()
{
    cin>>a>>b;
    for(int i=a; i<=b; i++)
    {
        int sum = i;//要先把i赋给sum,再用sum去迭代,否则用i迭代就不能标记i了
        if(visit[i] == -1)
            continue;
        while(1)
        {
            sum = happynum(sum);//递归求出每次的过程数
            if(sum == 1)//如果是幸福数
            {
                visit[i] = 1;
                for(auto it=v.begin(); it!=v.end(); it++)//迭代器,把在v容器中的过程数都视为不是特立独行的
                    visit[*it] = -1;
                num[i] = v.size() + 1;//把自己也要算上
                v.clear();//进行下次循环前把v清空
                break;
            }
            if(find(v.begin(),v.end(),sum) != v.end())//如果在v中找到了当前的sum,证明他是循环的数,不是幸福数
            {
                v.clear();//直接清空v容器,进行下次循环
                break;
            }
            v.push_back(sum);//将这个数的过程数存入v中
        }
    }
    int flag = 0;//是否有特立独行幸福数的标志
    for(int i=a; i<=b; i++)
    {
        if(visit[i] == 1)
        {
            cout<<i<<" ";
            if(isprime(i))
                cout<<num[i]*2<<endl;
            else
                cout<<num[i]<<endl;
            flag = 1;
        }
    }
    if(!flag)
        cout<<"SAD";
}

知识总结:

知识点就还是STL容器中的vector容器,主要是思路。这个题目说白了还是和水仙花数一类的东西,还是数学性强一点吧。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这道题目是一道算法题,需要我们设计一个算法来解决问题。具体来说,我们需要找到一种方法,使得在一个给定的序列中,能够找到一个子序列,使得该子序列中的所有元素都是不同的,并且该子序列的长度最长。 这个问题可以使用贪心算法来解决。具体来说,我们可以从序列的第一个元素开始,依次向后遍历每个元素。对于每个元素,我们可以将其加入到当前的子序列中,如果该元素已经在子序列中出现过了,那么我们就需要将子序列中该元素之前的所有元素都删除,然后再将该元素加入到子序列中。这样,我们就可以保证子序列中的所有元素都是不同的,并且该子序列的长度最长。 具体的实现过程可以参考以下代码: ```python n = int(input()) a = list(map(int, input().split())) s = set() ans = j = for i in range(n): while a[i] in s: s.remove(a[j]) j += 1 s.add(a[i]) ans = max(ans, len(s)) print(ans) ``` 在这段代码中,我们使用了一个集合 `s` 来保存当前的子序列。对于每个元素 `a[i]`,我们首先判断它是否已经在集合中出现过了,如果是的话,就需要将集合中该元素之前的所有元素都删除,然后再将该元素加入到集合中。最后,我们更新答案 `ans`,使其等于当前子序列的长度和之前的答案中的较大值。 这样,我们就可以通过贪心算法来解决这个问题了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值