zoukankan      html  css  js  c++  java
  • UVa 1210 (高效算法设计) Sum of Consecutive Prime Numbers

    题意:

    给出n,求把n写成若干个连续素数之和的方案数。

    分析:

    这道题非常类似大白书P48的例21,上面详细讲了如何从一个O(n3)的算法优化到O(n2)再到O(nlogn),最后到O(n)的神一般的优化。

    首先筛出10000以内的素数,放到一个数组中,然后求出素数的前缀和B。这样第i个素数一直累加到第j个素数,就可表示为Bj - Bi-1

    枚举连续子序列的右端点j,我们要找到Bj - Bi-1 = n,也就是找到Bi-1 = Bj - n。

    因为Bj是递增的,所以Bi-1也是递增的,所以我们就不用从头枚举i,而是接着上一次循环i的值继续枚举。

    还有就是,因为本身素数也是递增的(废话!),所以j也不一定要枚举到最后一个素数,只要在不超过n的素数里枚举就行了。

    说了这么多,我就是想说人家算法的效率已经很高了,15ms,UVa上居然排300+名,鄙视那些打表狗。

     1 #include <cstdio>
     2 #include <cmath>
     3 
     4 const int maxn = 10000;
     5 const int maxp = 1300;
     6 bool vis[maxn + 10];
     7 int prime[maxp], sum[maxp], cnt = 1;
     8 
     9 void Init()
    10 {
    11     int m = sqrt(maxn + 0.5);
    12     for(int i = 2; i <= m; ++i) if(!vis[i])
    13         for(int j = i * i; j <= maxn; j += i) vis[j] = true;
    14     for(int i = 2; i <= maxn; ++i) if(!vis[i]) prime[cnt++] = i;
    15     cnt--;
    16     //求素数的前缀和
    17     for(int i = 1; i <= cnt; ++i) sum[i] = sum[i - 1] + prime[i];
    18 }
    19 
    20 int main()
    21 {
    22     Init();
    23     int n;
    24     while(scanf("%d", &n) == 1 && n)
    25     {
    26         int i = 0, ans = 0;
    27         for(int j = 1;j <= cnt && prime[j] <= n; ++j)
    28         {
    29             int temp = sum[j] - n;
    30             while(sum[i] < temp) ++i;
    31             if(sum[i] == temp) ans++;
    32         }
    33         printf("%d
    ", ans);
    34     }
    35 
    36     return 0;
    37 }
    代码君
  • 相关阅读:
    程序调试的利器GDB
    Building a Android Development Environment
    手机的串号IMEI/ESN标示位置图解摩托罗拉官方教程
    Linux调试信息输出串口设备号的设置
    git忽略文件提交
    Spring @Transactional事务传播范围以及隔离级别
    自定义springbootstarter
    maven 命令将jar包安装到本地仓库
    oracle 常用命令
    Oracle 用户(user)和模式(schema)的区别
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4204871.html
Copyright © 2011-2022 走看看