湘潭市比赛A题 Anti-Goldbach's Conjecture

链接:http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1140
看到题目首先就想到打表,打表这个过程是没错,但是,打表后该怎么做了,这题目有点蛋疼,输出的时候
要输出的它前面的数包括他自己的总和,首先朴素的枚举他前面的所有答案,然后加起来,肯定会超时的。

这题可以打奇合数的表,可以打素数的表,可以找规律,每次方法对应不同的算法,我是打奇合数的表
因为每有一个奇合数,这个奇数,就对应了一个方案,因为在此题目中的要满足奇数=奇合数+偶合数,
顺带一提而且这个奇数A,只有A-4之前的奇合数才能满足要求,比如17的前面奇合数有915而15不满足,因为
没有一个和15配对的合数,所以只要算A-4之前的奇合数就行
打完奇合数表就完成第一步了,然后就是怎样算出它前面的数的方案数的总和,我这里用了一个数组
bx[i]表示i这个数之前有多少个奇合数,ax[i]是打出的奇合数的表,满足要求的是1,其他为0
for(len=0,i=9;i<=1000000;i++)
 
    {
      if(ax[i])
      len++;
      bx[i+4]=len;
      }
这里加4不明白 请参考前面红字部分说的
然后后面复杂度就减少了,还要用64为防溢出.
AC代码如下:
#include <stdio.h>
#include <math.h>
#include <string.h>
long long ax[1000005]={0};
long long bx[1000005]={0};
long long cx[1000005]={0};
int main()
{
    long long i,j,k,m,len=0,a;
    for(i=2;i<=500000;i++)
    {
        for(j=i+i;j<=1000000;j+=i)
        {
        if(j%2==1)
        ax[j]=1;
        }
    }
    for(i=9;i<=1000000;i++)
    {
    if(ax[i])
    len++;
    bx[i+4]=len;
    }
    while(scanf("%I64d",&a)!=EOF)
    {
        long long sum=0;
    for(i=13;i<=a;i+=2)
    sum+=bx[i];
        printf("%I64d\n",sum);
    }
}


你可能感兴趣的:(算法)