POJ_2739

//196k  0ms

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>

using namespace std;

int main() {
  bool is_prim[10001];
  memset(is_prim, true, 10001);
  for (int i = 2; i < 10001; ++i) {
    if (!is_prim[i])
      continue;
    for (int j = i * 2; j < 10001; j += i) {
      if (is_prim[j])
        is_prim[j] = false;
    }
  }
  vector<int> prim;
  for (int i = 2; i < 10001; ++i) {
    if (is_prim[i])
      prim.push_back(i );
  }
  int n;
  scanf("%d", &n);
  while (n) {
    int sum = 2, cnt = 0;
    int st = 0, end = 0;
    while (prim[end] <= n) {
      if (sum == n) {
        ++cnt, ++end;
        sum = sum + prim[end];
      }
      if (sum < n) {
        ++end;
        sum += prim[end];
      }
      if (sum > n) {
        sum -= prim[st];
        ++st;
      }
    } 
    printf("%d\n", cnt);
    scanf("%d", &n);
  }
  return 0;
}


notes: 题目有两个优化点

1. 空间换时间,由于题目输入是在[2, 10000]之间,因此首先采用筛选法,将所有范围内的质数计算出来并存储,这样对避免了对每个输入重复计算的时间消耗。

2. 由于题目要求是连续的素数组合,因此采用滑动窗口,在查找组合时候能够达到O(n),比二重循环快两个量级。


                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值