全国青少年信息学奥林匹克竞赛(信奥赛)备考实战之循环结构(for循环语句)—(十)(求解数学中特殊的数)

发布于:2025-02-11 ⋅ 阅读:(44) ⋅ 点赞:(0)

实战训练1—完全数

问题描述:

数学上的“完全数”是指真因子(除了自身以外的约数)之和等于它本身的自然数。例如,6的因子是1,2,3,而1+2+3=6,所以6是完全数。如果一个正整数小于它的所有真因数之和,被称为“不足数”。如果一个正整数大于它的所有真因数之和,被称为“过剩数”。编程实现判断一个正整数是完全数、不足数还是过剩数。

输入格式:

输入一行,包含一个正整数n

输出格式:

输出一行,如果n是完全数,则输出"Perfect",不足数则输出"Deficient",过剩数则输出"Abundant"。

输入输出样例:

输入样例1

输出样例1

28

Abundant

输入样例2

输出样例2

11

Deficient

输入样例3

输出样例3

36

Abundant

问题分析:

根据题意,对于正整数n需要计算其所有正因子(不包括它本身)的和,借鉴求素数的思想,从1开始到n-1结束依次去整除n,使用循环来实现,循环变量i初始值为1,终值为n-1,更新表达式为自增运算,循环体内循环变量依次去整除n,如果n%i==0,那么将i累加到因子和,最后判断因子和是否等于它本身,等于则这个数是完全数,小于则为不足数,否则为过剩数。具体程序代码如下:


#include<bits/stdc++.h>
using namespace std;
int main() {
	int n,sum=0;//定义正整数n和,因子和变量sum并初始化为0
	cin>>n;//输入n
	for(int i=1; i<n; i++) {//定义循环变量i,从1到n-1 
		if(n%i==0) {//循环变量i依次去整除n,判断i是否为n的因子 
			sum += i;//将因子i累加到和变量sum中 
		}
	}
	if(sum==n) {//判断sum是否和该数相等 
		cout<<"Perfect"<<endl;//完全数 
	} else if(sum>n) {//判断sum是否大于n 
		cout<<"Abundant"<<endl;//过剩数 
	} else {
		cout<<"Deficient"<<endl;//不足数 
	}
	return 0;
}

 在判断素数时,对代码进行了改进,每个数的因子是成对出现的,所以找到一个因子之后,让n去除以该因子得到另一个因子,当然需要考虑这两个因子是否相等,同时需要将该数本身去除出去,可以将循环变量的终值修改为sqrt(n),这样减少了代码循环次数,提高了效率。具体程序代码如下:


#include<bits/stdc++.h>
using namespace std;
int main() {
	int n,sum=0;//定义正整数n和,因子和变量sum并初始化为0
	cin>>n;//输入n
	for(int i=1; i<=sqrt(n); i++) {//定义循环变量i,从1到sqrt(n) 
		if(n%i==0) {//循环变量i依次去整除n,判断i是否为n的因子 
			if(i != n/i){//判断两个因子是否相等,如果不相等进入本分支 
				sum += i;//将因子i累加到和变量sum中 
				if(n/i != n){//需要考虑i为1时,另一因子是该数本身,所以不能将本身累加到和sum中 
					sum += n/i;//将另一个因子n/i累加到和变量sum中 
				}
			}else{//两个因子相等
				sum += i;//两个因子相等只需累加一次 
			} 		
		}
	}
	if(sum==n) {//判断sum是否和该数相等 
		cout<<"Perfect"<<endl;//完全数 
	} else if(sum>n) {//判断sum是否大于n 
		cout<<"Abundant"<<endl;//过剩数 
	} else {
		cout<<"Deficient"<<endl;//不足数 
	}
	return 0;
}

实战训练2—寻找指定范围的完全数

问题描述:

数学上的“完全数”是指真因子(除了自身以外的约数)之和等于它本身的自然数。例如,6的因子是1,2,3,而1+2+3=6,所以6是完全数。输入两个整数m和n,且m<=n,输出m到n这个范围内所有的完全数。

输入格式:

输入一行,两个整数m和n,且m<=n。

输出格式:

输出一行,输出所有的完全数,完全数之间用一个空格隔开。

输入输出样例:

输入样例

输出样例

2 10001

6 28 496 8128

问题分析:

通过实战训练2可知判断一个整数是否为完全数时采用单层循环,现在该训练修改为统计某个范围内的完全数,即对该范围内的所有整数,依次去判断该整数是否为是否为完全数,因此需要采用for循环嵌套来实现,外层循环变量i表示整数范围m到n,内层循环变量j表示是否为i的因子,j的取值从1到i-1,用j去整除i。具体程序代码如下:


#include<bits/stdc++.h>
using namespace std;
int main() {
	int m,n;//定义正整数范围m和n
	cin>>m>>n;//输入m和n的值 
	for(int i=m;i<=n;i++){//定义外层循环,循环变量i从m到n 
        int sum =0;//定义因子和变量sum,并初始化为0 
        for(int j=1;j<i;j++){//定义内层循环,循环变量j依次去整除i,判断j是否为i的因子
            if(i%j==0){//如果i能被j整除 
                sum += j;//将因子j累加到和变量sum中 
            }
        }
        if(sum == i){//如果因子和等于该数本身,则为完全数 
            cout<<i<<" ";//输出该完全数i 
        }
    }
	return 0;
}

 同理将内层循环的终值值设置为sqrt(i),程序代码如下:


#include<bits/stdc++.h>
using namespace std;
int main() {
	int m,n;//定义正整数范围m和n
	cin>>m>>n;//输入m和n的值
	for(int i=m; i<=n; i++) { //定义外层循环,循环变量i从m到n
		int sum =0;//定义因子和变量sum,并初始化为0
		for(int j=1; j<=sqrt(i); j++) {//定义循环变量j,从1到sqrt(i)
			if(i%j==0) {//循环变量j依次去整除i,判断j是否为i的因子
				if(j != i/j) { //判断两个因子是否相等,如果不相等进入本分支
					sum += j;//将因子j累加到和变量sum中
					if(i/j != i) { //需要考虑j为1时,另一因子是该数本身,所以不能将本身累加到和sum
						sum += i/j;//将另一个因子i/j累加到和变量sum中
					}
				} else { //两个因子相等
					sum += j;//两个因子相等只需累加一次
				}
			}
		}
		if(sum == i) { //如果因子和等于该数本身,则为完全数
			cout<<i<<" ";//输出该完全数i
		}
	}
	return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到