Friends number
----------------------------------------------------------------------------(
题目链接 )
题目大意:
对于两个数,如果一个数的除去本身的所有因子和是另一个数,而且另一个数的除去本身的所有因子和是这个数
那么这两个数互为朋友数
下面给你一个区间,求在这个区间内,有多少对朋友数!
这道题其实不难,但是我没有想到
可能我对于素数打表理解的不够深刻!不能够举一反三,闭门思过····
这道题我们也是预处理
将每个数的因子和全部存起来
可以先自己想一想,实在想不出再看题解!
如果你想到如何把每个数的因子全部存起来,
那么这道题也就差不多A了
====================================================================================
代码及代码详解如下
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
using namespace std;
#define N 5000001
#define CLR(arr, what) memset(arr, what, sizeof(arr))
int a[N],pre[N],last[N],ss=0;
void getsum();
int main()
{
for(int i=2; i<=N; i++)//a数组全部初始化为1
{
a[i]=1;
}
for(int i=2; i*i<=N; i++)//这一步很巧妙,将一个数的所有因子和加起来存上
{
for(int j=i; i*j<=N; j++)
{
a[i*j]+=i+j; //比如a【6】+=2+3;因子和为5
} //(因子1没有算,因为上面初始化的时候已经加上了)
}
for(int i=1; i<=N; i++)
{
int t=a[i]; //如果i个数的因子和大于i并且小于N
if (t>i && t<=N&& a[t]==i)//且这个数的因子和的因子和是i
{
pre[ss]=i;//那么将这个数存到pre数组中
last[ss]=t;//将这个数的friend number存到last中
ss++;
}
}
int m,i,j,n;
while(~scanf("%d%d",&m,&n))
{
int count = 0;
for(i=0; i<ss; i++)
{
if(pre[i]>=m&&last[i]<=n)//数一下存了多少个数
{
count++;
}
}
printf("%d\n",count);
}
return 0;
}