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;
}

 



posted @ 2013-04-21 23:47  Titanium  阅读(403)  评论(0编辑  收藏  举报