七夕节 |
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) |
Total Submission(s): 3917 Accepted Submission(s): 1381 |
|
Problem Description 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!" ![]()
|
Input 输入数据的第一行是一个数字T(1<=T<=500000),它表明测试数据的组数.然后是T组测试数据,每组测试数据只有一个数字N(1<=N<=500000).
|
Output 对于每组测试数据,请输出一个代表输入数据N的另一半的编号.
|
Sample Input 321020
|
Sample Output 1822
|
解题思路
因为是求不大于他本身的因子之和,所以sum可以初始化为1.当然对于求它的所有因子不需要从2判断到他本身,为了优化节省时间,可以只判断到sqrt(n),若之前的i为他的一个因子,那sum+=i+n/i;因子之和可以同时加上i和n/i的值,相当于一下加了两个因子。当然最后要特殊处理一下sqrt(n),若其为整数则加上。
对于sqrt(n)是否是整数,曾经我的判断过程是: sqrt(n)-(int)sqrt(n)==0,今天突然想到,当在求其因子的时候,i是递增的,当判断到<sqrt(n)时跳出,而这时i的值正好处于一个特殊的地位,若sqrt(n)为整数,那么此时i==sqrt(n),那么i*i==n;若sqrt(n)不为整数,那么i就要比sqrt(n)大,那么i*i>n。
代码
<span style="font-size:18px;">#include<stdio.h>
#include<math.h>
int main()
{
int n;
int t;
int i,j,sum;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
sum=1;
for(i=2;i<sqrt(n);i++)
if(n%i==0)
sum+=i+n/i;
if(i*i==n) //因为上面的 i判断到 sqrt(n)之前,而 i的值正好为sqrt(n)
sum+=i; //如果 sqrt(n)的值为整数,则符合题意。不用再去用 sqrt(n)-(int)sqrt(n)==0去判断
printf("%d\n",sum);
}
return 0;
}
</span>