不可摸数
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 10007 Accepted Submission(s): 2589
Problem Description
s(n)是正整数n的真因子之和,即小于n且整除n的因子和.例如s(12)=1+2+3+4+6=16.如果任何
数m,s(m)都不等于n,则称n为不可摸数.
Input
包含多组数据,首先输入T,表示有T组数据.每组数据1行给出n(2<=n<=1000)是整数。
Output
如果n是不可摸数,输出yes,否则输出no
Sample Input
3 2 5 8
Sample Output
yes yes no
C语言程序代码
/*
解题思路::
标准的筛选法---求出每个数的因子和,
然后看因子和是否在1000以内,是的话就证明等于因子和的这个数是不可摸数
第一次接触筛选法,感觉这算法太牛了。
主要是理解筛选法。
以以下代码为例:主要思路为。
i=1 : a[2]=0+1=1;
a[3]=0+1=1
a[4]=0+1=1;
a[5]=0+1=1;
a[6]=0+1=1;
a[7]=0+1=1;
a[8]=0+1=1;
a[9]=0+1=1;
a[10]=0+1=1;
a[11]=0+1=1
a[12]=0+1=1;
.
.
.
i=2 : a[4]=a[4]+2=1+2=3 //此时a[2]、a[3]被筛出,其值为1.
a[6]=1+2=3
a[8]=1+2=3;
a[10]=1+2=3
a[12]=1+2=3;
.
.
.
i=3 : a[6]=3+3=6;//此时a[4]被筛出。
a[9]=1+3=4
a[12]=3+3=6
.
.
.
下面以此类推。
*/
#include<stdio.h>
#include<string.h>
#include<math.h>
#define M 500001
int a[M];
int b[1001];
int f(){
int i,j,l;
for(i=1;i<=M/2;i++)
for(j=i+i;j<=M;j+=i)
a[j]+=i;
for(i=1;i<=M;i++)
{
if(a[i]<=1000)
b[a[i]]=1;
}
}
int main(){
int t,n,m,i,j;
scanf("%d",&t);
f();
while(t--)
{
scanf("%d",&n);
if(b[n])
printf("no\n");
else
printf("yes\n");
}
return 0;
}