zoukankan      html  css  js  c++  java
  • poj_2739 尺取法

    题目大意

        给定一个数字N,N可能由1个或多个连续的素数求和得到,比如41 = 2+3+5+7+11+13, 41 = 11+13+17, 41 = 41。求出对于N,所有可能的组合形式。

    题目分析

        先求出所有可能构成加数的素数,使用埃氏筛选法。然后求出所有的可能形式,由于所选择的是一个连续的区间,可以使用一个头指针,一个尾指针,区间选择为头尾指针内部的区域,通过头尾指针的移动来更改区间。即尺取法。 
        尾部保持不动,不断增加头部,并加上头部数据,记录区间内的和,若恰好等于n,则计数加1,若大于等于n,则不断的减去尾部的数据....

    实现(c++)

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    bool is_primes[10005];
    int primes[10005];
    int prime_count;
    //埃氏筛法 求质数
    void GetPrimes(int n){
    	int k = 0;
    	memset(is_primes, true, sizeof(is_primes));
    	for (int i = 2; i <= n; i++){
    		if (!is_primes[i])
    			continue;
    		primes[k++] = i;
    		for (int m = 1; m*i <= n; m++)
    			is_primes[m*i] = false;
    	}
    	prime_count = k;
    }
    int main(){
    	int n;
    	GetPrimes(10000);	//获得10000 以内的所有质数
    
    	while (scanf("%d", &n) && n){
    		int sum = 0;
    		int s = 0, t = 0;
    		int count = 0;
    		//尺取法
    		for (;;){
    			while (primes[t] <= n && sum < n){	//若小于n则头部一直增加,直到大于等于n
    				sum += primes[t++];
    			}
    			if (sum == n)	//计数
    				count++;
    			
    			sum -= primes[s++];	//减去头部
    			
    			if (sum <= 0)	//说明尾部一直没有增加,且头部赶上了尾部,结束
    				break;
    		}
    		printf("%d
    ", count);
    	}
    	return 0;
    }
    
  • 相关阅读:
    11 数据的增删改
    10 外键的变种 三种关系
    09 完整性约束
    03 body标签中的相关标签
    02 body标签中的相关标签
    01 HTML介绍和head标签
    08 数据类型(2)
    07 数据类型
    06 表的操作
    偶遇RecyclerView内部Bug
  • 原文地址:https://www.cnblogs.com/gtarcoder/p/4908524.html
Copyright © 2011-2022 走看看