数论数

目录

一,完全数

1,完全数

2,OJ实战

HDU 1406 完数

力扣 507. 完美数

二,快乐数

力扣 202. 快乐数

​三,平方和

力扣 633. 平方数之和


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

一,完全数

1,完全数

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

(1)计算机求解

利用模板很容易求出1亿之内的完全数:

int main() {
	for (int i = 1; i <= 100000000; i++) {
		auto v = GetDivisors(i);
		int s = 0;
		for (auto x : v)s += x;
		if (s == i*2)cout << i << " ";
	}
	return 0;
}

求出1亿之内只有5个完全数:6, 28, 496, 8128, 33550336

(2)数学求解

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

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

奇完全数还没有定论,如果存在的话,最小的奇完全数也一定很大。

2,OJ实战

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

代码:

#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的大小

力扣 507. 完美数

对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」

给定一个 整数 n, 如果是完美数,返回 true;否则返回 false

示例 1:

输入:num = 28
输出:true
解释:28 = 1 + 2 + 4 + 7 + 14
1, 2, 4, 7, 和 14 是 28 的所有正因子。

示例 2:

输入:num = 7
输出:false

提示:

  • 1 <= num <= 108
class Solution {
public:
	bool checkPerfectNumber(int num) {
		return num==6||num==28||num==496||num==8128||num==33550336;
	}
};

二,快乐数

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);
	}
};

​三,平方和

力扣 633. 平方数之和

给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。

示例 1:

输入:c = 5
输出:true
解释:1 * 1 + 2 * 2 = 5

示例 2:

输入:c = 3
输出:false

提示:

  • 0 <= c <= 231 - 1
class Solution {
public:
    bool judgeSquareSum(int c) {
        return Facs::isSquareSum(c);
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值