HDOJ-1999 不可摸数

不可摸数

转自:http://www.cnblogs.com/dongsheng/archive/2012/08/18/2645594.html

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 }

 

你可能感兴趣的:(OJ)