原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1215
题解:第一次做这个题,明知道普通方法会超时,但是我还是试了一下,果然
超时代码如下:
#include<iostream>
using namespace std;
int main() {
int n;
cin >> n;
while (n--) {
int num;
cin >> num;
int sum = 0;
for (int i = 1;i*2 <= num;i++) {
if (num%i == 0)
sum += i;
}
cout << sum << endl;
}
}
看了看讨论区,知道要优化的,可以从1到n的根号结束,因为是乘法所以最大到根号处结束,比如12,算2的时候,顺便加上6,算3的时候顺便加上4,这样到3就可以结束了,避免遍历全部,如果碰上平方数,加一次根号就行了
代码:
#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;
int main() {
int n;
scanf("%d", &n);
while (n--) {
int num;
scanf("%d", &num);
int sum = 0;
int temp = sqrt(num);
for (int i = 1;i <= temp;i++) {
if (num%i == 0) {
sum += i;
if (i != 1 && i != num / i)
sum += num / i;
}
}
printf("%d\n", sum);
}
}
也可以打表,这个思想就类似开灯问题
参考博客:http://blog.csdn.net/hurmishine/article/details/51337351
代码:
#include<iostream>
#include <stdio.h>
using namespace std;
int a[500001];
int main()
{
int n, i, num, j;
scanf("%d", &n);
a[0] = a[1] = 1;
for (i = 1;i <= 500000 / 2;i++)
for (j = i * 2;j <= 500000;j += i)
a[j] += i; /类似开灯问题
while (n--)
{
scanf("%d", &num);
printf("%d\n", a[num]);
}
return 0;
}