hdu1215七夕节求因子和

hdu 七夕节

题目链接

题目描述

有T个样例,每个样例给定一个N,将所给N的所有因子相加求和。N的因子就是所有比N小又能被N整除的所有正整数。如12的因子有1,2,3,4,6。(T(1<=T<=500000),N(1<=N<=500000))

解题思路

这个题思路很简单,可能你首先想到了不就是从1到n进行遍历,找他的因子,再用一个变量计算因子和不就可以了么。但是我们观察到,样例个数T和给定的N都可能会很大,假如直接遍历1到N,那么时间复杂度就会很大,会导致超时。所以我们就想,怎么可以简化这个循环遍历的过程呢。

我们就可以想到,这些数字是有相关性的,比如当你遍历发现2是10的因子,那么10/2=5,5也是10的因子,这样我们就简化了循环,只需要遍历到 i * i <= N的情况。也就是如下代码:

int sum = 0;
for(int i = 1; i*i<=n; i++) {
	if(n%i==0) {
		sum += (i+n/i);
	}
}

但是有几个小细节需要注意,比如因为题目中说,因子要小于N,那么在变量 i 循环到 1 的时候,就不能把N/1=N加进去,还有当i * i刚好为N时,我们只需要加一遍 i 就可以了,而不需要把 i 和 N/i 都加进去。所以要判断一下这两种特殊情况。

具体代码

对于我上面提到的两种特殊情况,也可以用其他的方法进行处理。

#include<cstdio>
#include<algorithm>
using namespace std;

int main() {
	int t;
	scanf("%d",&t);
	while(t--) {
		int n;
		scanf("%d",&n); 
		int sum = 1; //初始化sum = 1,相当于把 i = 1的情况已经处理了。
		for(int i = 2; i*i<=n; i++){ //直接从2开始循环
			if(i*i == n) { //特殊判断 i*i=n的情况
				sum += i;
			}
			else if(n%i==0) {
				sum += (i+n/i);
			}
		}
		if(n==1) printf("0\n");
		else {
			printf("%d\n",sum);
		}
	}
} 

猜你喜欢

转载自blog.csdn.net/weixin_43966538/article/details/106316521