scau ooxx numbers

数论+打表

A的所有因子和位B,B的所有的因子和为A,则称{A,B}是一对ooxx number

输入数字n,求出[1,n]里面有多少对ooxx number,其中(A,B),(B,A)这样算作一对

n最大为5百万(50000000)

 

hits 

220=  (1+2+4+71+142)  <---  284,

284=  (1+2+4+5+10+11+20+22+44+55+110)   <---   220。

220 and 280 is a pair of ooxx numbers

sample input

300
1300

sample output
1
2


定义sum[i]=i的因子和,用筛法来构建i
枚举因子i,那么2i,3i,4i…………都包含i这个因子,i都是它们因子和的一部分,所以要 sum[2i] += i; sum[3i] += i; sum[4i] += i;
用筛法能求出所有的sum[i],不过还没完,它们都缺了1,不过可以等下加进去即可

然后就是看看所有的sum[i],
m = sum[i] + 1 , 且 i = sum[m] + 1 ;
那么(m,i)就是一对ooxxnumber,这这个判断只需要扫一遍sum数组即可

以上过程可以记录下所有的对,用时大概是2s多,会发现这些对其实不多,直接输出到文件中,然后打表即可
在每个case中输入n后,扫描对,找到合适的对就计数


打表程序
#include <cstdio>

#include <cstring>



const int N = 5000000 ;



int sum[N+10];



void init()

{

   memset(sum,0,sizeof(sum));

   int m = N/2;

   for(int i=2; i<=m; i++)

      for(int j=i+i; j<=N; j+=i)

         sum[j] += i;



   for(int i=2; i<=N; i++)

   {

      int mm= sum[i]+1;

      if(mm <= N && mm>i && sum[mm]+1 == i )

         printf("%d,%d,",i,mm);

   }

}



int main()

{

   freopen("list.txt","w",stdout);

   init();

   return 0;

}

 

 

最后的程序

#include <cstdio>

#include <cstring>



int sum[10000][2]={220,284,1184,1210,

                 2620,2924,5020,5564,

                 6232,6368,10744,10856,

                 12285,14595,17296,18416,

                 63020,76084,66928,66992,

                 67095,71145,69615,87633,

                 79750,88730,100485,124155,

                 122265,139815,122368,123152,

                 141664,153176,142310,168730,

                 171856,176336,176272,180848,

                 185368,203432,196724,202444,

                 280540,365084,308620,389924,

                 319550,430402,356408,399592,

                 437456,455344,469028,486178,

                 503056,514736,522405,525915,

                 600392,669688,609928,686072,

                 624184,691256,635624,712216,

                 643336,652664,667964,783556,

                 726104,796696,802725,863835,

                 879712,901424,898216,980984,

                 947835,1125765,998104,1043096,

                 1077890,1099390,1154450,1189150,

                 1156870,1292570,1175265,1438983,

                 1185376,1286744,1280565,1340235,

                 1328470,1483850,1358595,1486845,

                 1392368,1464592,1466150,1747930,

                 1468324,1749212,1511930,1598470,

                 1669910,2062570,1798875,1870245,

                 2082464,2090656,2236570,2429030,

                 2652728,2941672,2723792,2874064,

                 2728726,3077354,2739704,2928136,

                 2802416,2947216,2803580,3716164,

                 3276856,3721544,3606850,3892670,

                 3786904,4300136,3805264,4006736,

                 4238984,4314616,4246130,4488910,

                 4259750,4445050

                 };



int main()

{

   int n;

   while(scanf("%d",&n)!=EOF)

   {

      int res = 0;

      for(int i=0; sum[i][0]!=0 && sum[i][0] < n; i++)

      {

         if(sum[i][0] <= n && sum[i][1] <= n)

            res ++;

      }

      printf("%d\n",res);

   }

   return 0;

}

 



你可能感兴趣的:(number)