不可摸数
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5296 Accepted Submission(s): 1393
Problem Description
s(n)是正整数n的真因子之和,即小于n且整除n的因子和.例如s(12)=1+2+3+4+6=16.如果任何
数m,s(m)都不等于n,则称n为不可摸数.
数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
//基本思想,如果一个数能被1000除尽(求余为0)直接跳过,且用标记或者直接把因子和小于1001的存储于一个新数组中 #include <iostream> #include <cstdlib> #include <cstring> #include <algorithm> using namespace std; const int N = 1000000; int vis[N]; int ans[1005]; void init() { int i,j,k; memset(ans,0,sizeof(ans)); fill(vis,vis+N,1); vis[0] = 0; vis[1] =0; /*超时 for(i=2; i<=N; i++) { int sum = 0; //还可以再次优化,先把vis[2]=1,在遇到其他素数直接跳过 if(i%1000==0) continue; j=1; while(j<=i/2) { if(i%j==0) sum += j; j++; } vis[i] = sum; } */ for(i=2;i<=N/2;i++) for(j=2*i;j<N;j+=i) //不能是i*i vis[j] += i; for(i=2;i<N;i++) if(vis[i]<=1000) ans[vis[i]] = 1; } int main() { // freopen("1.txt","r",stdin); //freopen("3.txt","w",stdout); int i,j,k,T; init(); cin>>T; while(T--) { int num; cin>>num; if(ans[num]) cout<<"no"<<endl; else { cout<<"yes"<<endl; } } return 0; }