不可摸数

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5334    Accepted Submission(s): 1405


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
 
  1 /*
  2 //代码一:-----超时
  3 #include<stdio.h>
  4 #include<math.h>
  5 
  6 int fun(int num)
  7 {
  8     int i,k=0;
  9     for(i=1;i<=(int)sqrt(num);++i)
 10         if(num%i==0)
 11         {
 12             if(num/i!=i)
 13             {
 14                 k+=i;
 15                 k+=num/i;
 16             }
 17             else
 18                 k+=i;
 19         }
 20     return k;
 21 }
 22 
 23 int main()
 24 {
 25     int T,i,n,flag;
 26     scanf("%d",&T);
 27     while(T--)
 28     {
 29         flag=0;
 30         scanf("%d",&n);
 31         for(i=1;i<=(n-1)*(n-1);++i)
 32         {
 33             if(fun(i)==n)
 34             {
 35                 flag=1;
 36                 break;
 37             }
 38         }
 39         if(flag)
 40             printf("no\n");
 41         else
 42             printf("yes\n");
 43     }
 44     return 0;
 45 }
 46 
 47 
 48 
 49 */
 50 
 51 
 52 /*
 53 代码二:---AC
 54 标准的筛选法---求出每个数的因子和,
 55 然后看因子和是否在1000以内,是的话就证明等于因子和的这个数是不可摸数。
 56 */
 57 #include<stdio.h>
 58 #define MAX 500001   //这题数据求到这里就可以了
 59 
 60 int sum[MAX];
 61 int flag[1001];
 62 
 63 void init()   //筛选法算出1000内存在的的因子和
 64 {
 65     int i,j;
 66     for(i=1;i<=MAX/2;++i)  //不知道为啥 这里开到刚超出1000了就不对
 67         for(j=i+i;j<MAX;j+=i)
 68             sum[j]+=i;
 69     for(i=1;i<MAX;++i)
 70         if(sum[i]<=1000)
 71             flag[sum[i]]=1;
 72 }
 73 
 74 
 75 int main()
 76 {
 77     int T,n;
 78     init();
 79 //    printf("%d\n",sum[500000]);
 80     scanf("%d",&T);
 81     while(T--)
 82     {
 83         scanf("%d",&n);
 84         if(flag[n])
 85             printf("no\n");
 86         else
 87             printf("yes\n");
 88     }
 89     return 0;
 90 }
 91 
 92 
 93 
 94 
 95 /*
 96 
 97 对于这个题有两个引理和公认:
 98 1.     若x为大于2的偶数,那么s(x)>x/2;
 99 2.     若x是一个正奇数,而s(x)是偶数,那么x必然是一个平方数。
100 3.     只有一个不可摸数是奇数,那是5
101 有以上三个结论,便可以算出一定范围内的不可摸数。
102 
103 代码三:
104 */
105 #include <iostream>
106 using namespace std;
107 int  arry[1005];
108 
109 void check()
110 {
111     int sum;
112     for(int i=2;i<=2000;i+=2) 
113     {
114         sum=0;
115         for(int j=1;j<=i/2;++j)
116         {
117             if(i%j==0)
118                 sum+=j;
119         }
120         if(sum<=1000)
121             arry[sum]=1;
122     }
123     for(int i=3;i<=1000;i+=2)
124     {
125         sum=0;
126         for(int j=1;j<=(i*i)/2;j+=2)
127         {
128             if((i*i)%j==0)
129                 sum+=j;
130         }
131         if(sum<=1000)
132             arry[sum]=1;
133     }
134 
135 }
136 int main()
137 {
138     check();
139     int t;
140     scanf("%d",&t);
141     while(t--)
142     {
143         int n;
144         scanf("%d",&n);
145         if(n==5)
146             cout<<"yes"<<endl;
147         else 
148         {
149             if(arry[n]||n%2==1)
150                 cout<<"no"<<endl;
151             else 
152                 cout<<"yes"<<endl;
153         }
154     }
155     return 0;
156 }

 

posted on 2012-08-18 16:43  可笑痴狂  阅读(3143)  评论(0编辑  收藏  举报