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,否则输出noSample Input数m,s(m)都不等于n,则称n为不可摸数.
3 2 5 8Sample Output
yes yes no这一道题其实就算是卡数据了,好好学学求所有真因子之和,还有book[] 标记的位置;
代码:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#include<math.h>
#define Max 500000 // 卡数据;
int book[5000];
int sum[Max +10];
int main()
{
int i,j;
memset(book,0,sizeof(book));
memset(sum,0,sizeof(sum));
for(i = 1;i<=Max;i++)
{
for(j = 2;j*i<=Max;j++) // 1的 1 倍是本身,所以要从2倍开始;
{
sum[j*i] +=i;
}
if(sum[i]<=1010) // 这个一定要放循环里面;
book[sum[i]] = 1;
}
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
if(book[n])
printf("no\n");
else printf("yes\n");
}
return 0;
}
方法二:为什么要枚举 1~1000000;
代码二:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#include<math.h>
#define Max 1000
int book[Max];
//不可模数,s(m) 为 m的真因子和, 若所有的s(m) 不等于 n,那n就是 不可模数;
// 因为 判断的是 1000 以内的数到底 是不是不可模数,最大为1000,所以有可能一个数的单因子就是1000,
//因为判断素数时,判读的是根号n中的数,到底是不是n的因子,
// 就可以判断是不是素数了,(i是因子,n/i也是因子),找那个n的 sqrt(n) == 1000, 也是就 1000*1000了,
//
int main()
{
int i,j,t;
for(i = 1;i <= Max*Max;i++)
{
int sum = 0;
int k = sqrt(i) + 1;
int f = 1;
for(j = 1;j <= k;j++)
{
if(i%j==0)
{
t = i/j;
if(j==1&&i!=1||j==t)
sum += j;
else
{
sum += j;
sum += t;
}
}
if(sum>1000)
{
f = 0;
break;
}
}
if(f) book[sum] = 1;
}
int n;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
if(book[n])
printf("no\n");
else printf("yes\n");
}
return 0;
}