数论数HDU - 1406 完数

举报
用户已注销 发表于 2021/11/19 01:56:36 2021/11/19
1.4k+ 0 0
【摘要】 目录 一,完全数 HDU - 1406 完数 二,快乐数 力扣 202. 快乐数 数论里面有各种有趣的数。 一,完全数   HDU - 1406 完数 题目: 完数的定义:如果一个大于1的正整数的所有因子之和等于它的本身,则称这个数是完数,比如6,28都是完数:6=1+2+3;28=1+2+4+7+14...

目录

一,完全数

HDU - 1406 完数

二,快乐数

力扣 202. 快乐数


数论里面有各种有趣的数。

一,完全数

HDU - 1406 完数

题目:


完数的定义:如果一个大于1的正整数的所有因子之和等于它的本身,则称这个数是完数,比如6,28都是完数:6=1+2+3;28=1+2+4+7+14。 

本题的任务是判断两个正整数之间完数的个数。 
Input
输入数据包含多行,第一行是一个正整数n,表示测试实例的个数,然后就是n个测试实例,每个实例占一行,由两个正整数num1和num2组成,(1<num1,num2<10000) 。 
Output
对于每组测试数据,请输出num1和num2之间(包括num1和num2)存在的完数个数。 
Sample Input
2
2 5
5 7
Sample Output
0
1

数学里面,一般都是叫完全数

偶完全数很好求,因为欧拉求出了所有的偶完全数,它们有共同的表达式:

t*(t-1)/2

其中t=2^p,满足p为素数且t-1为素数

这样,我们可以轻松求出,10000以内只有4个完全数:4,28,496,8128

这个时候,再用从num1到num2的循环就不合适了,最好是用常数时间的算法

有个地方需要注意,num1和num2的大小关系未知

代码:


      #include<iostream>
      using namespace std;
      int main()
      {
     	int a, b;
      	cin >> a;
     	while (cin >> a >> b)cout << ((a - 6)*(b - 6) <= 0) + ((a - 28)*(b - 28) <= 0) + ((a - 496)*(b - 496) <= 0) + ((a - 8128)*(b - 8128) <= 0) << endl;
     	return 0;
      }
  
 

这个代码,自然是0ms AC了

因为写的时候a和b是对称的,所以不需要额外判断a和b的大小

二,快乐数

A happy number is defined by the following process: Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers, while those that do not end in 1 are unhappy numbers (or sad numbers).

一个数的所有数字的平方和,替换这个数本身,一直循环这个过程,如果最后能变成1那么就是Happy Number

首先,很显然,经过几次替换之后就会得到一个小于200的整数,

然后找规律,我们发现不是快乐数的数都会陷入同一个循环,循环里面最小的数是4,我们用程序验证一下:


      #include<iostream>
      using namespace std;
      int f(long long n)//求平方和
      {
         if (n == 0)return 0;
         return f(n / 10) + (n % 10)*(n % 10);
      }
      int main()
      {
         for(int i=1;i<200;i++){
             int n=i;
             while(n!=1&&n!=4)n=f(n);
              cout<<n<<" ";
          }
         return 0;
      }
  
 

可以发现有32个1和167个4

力扣 202. 快乐数

题目:

编写一个算法来判断一个数是不是“快乐数”。

一个“快乐数”定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。

示例: 

输入: 19
输出: true
解释: 
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

思路:

首先,很容易发现,所有的数经过若干次变换之后就最多三位数,而且不管再怎么变换都是最多三位数。

所以,所有的数最后都会进入循环。

其次,很容易发现,若干次变换之后一定会不超过162,而且不管再怎么变换都不超过162

只要枚举1到162经过若干次变换之后变成多少就行了。

结果是2个集合,一个是1,一个是{4,16,37......}

所以,所有的数经过若干次变换之后都会变成1或4

代码:


      class Solution {
      public:
     	bool isHappy(int n) {
     		if (n == 4)return false;
     		if (n == 1)return true;
     		int ans = 0;
     		while (n)
      		{
      			ans += n % 10 * (n % 10);
      			n /= 10;
      		}
     		return isHappy(ans);
      	}
      };
  
 

 

文章来源: blog.csdn.net,作者:csuzhucong,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/nameofcsdn/article/details/115706882

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

作者其他文章

评论(0

抱歉,系统识别当前为高风险访问,暂不支持该操作

    全部回复

    上滑加载中

    设置昵称

    在此一键设置昵称,即可参与社区互动!

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

    *长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。