POJ 2739

弱菜继续水题。。

Description

Some positive integers can be represented by a sum of one or more consecutive prime numbers. How many such representations does a given positive integer have? For example, the integer 53 has two representations 5 + 7 + 11 + 13 + 17 and 53. The integer 41 has three representations 2+3+5+7+11+13, 11+13+17, and 41. The integer 3 has only one representation, which is 3. The integer 20 has no such representations. Note that summands must be consecutive prime 
numbers, so neither 7 + 13 nor 3 + 5 + 5 + 7 is a valid representation for the integer 20. 
Your mission is to write a program that reports the number of representations for the given positive integer.

Input

The input is a sequence of positive integers each in a separate line. The integers are between 2 and 10 000, inclusive. The end of the input is indicated by a zero.

Output

The output should be composed of lines each corresponding to an input line except the last zero. An output line includes the number of representations for the input integer as the sum of one or more consecutive prime numbers. No other characters should be inserted in the output.
 
说白了就是输入一个数,输出它能由连续素数相加所表示的不同形式的个数,注意是连续的哦。
 
最早写了个递归的
import java.util.Scanner;
/*    
 *先一次性求出所有素数,开一个数组来存放 
 *而且是连续的素数相加,所以递归起来每次看前一个
 */
public class Main {
    private static int count;
    private static int[] primeSet = new int[1250];
    
    public static void findPrime(){
        boolean flag;
        primeSet[0] = 2;
        int k = 1;
        for(int i = 3; i <= 10020; i += 2){
            flag = true;
            for(int j = 3; j*j <= i; j += 2){
                if(i % j == 0){
                    flag = false;
                    break;
                }
            }
            if(flag)
                primeSet[k++]=i;
        }            
    }
    
    public static void findRepresentation(int num,int maxIndex){
        if(maxIndex < 0)
            return;
        if(num == primeSet[maxIndex])
            count++;
        else if(num > primeSet[maxIndex])
            findRepresentation(num - primeSet[maxIndex], --maxIndex);
    }
    
    public static void main(String[] args){
        findPrime();
        Scanner cin = new Scanner(System.in);
        int num;
        while((num=cin.nextInt())!=0){
            count = 0;
            if(num == 0)
                return;
            for(int i = 0; i < 1250 && primeSet[i] != 0; i++)
                if(num <= primeSet[i]){
                    if(num == primeSet[i])
                        count++;
                    for(int j=i-1; j>=0; j--)
                        findRepresentation(num, j);
                    break;
                }
                
            System.out.println(count);
        }
    }
}

后来看到别人写的http://www.cnblogs.com/leftcopy/archive/2012/03/06/2382549.html
确定是否素数这里比较特别,是从小每次相加一路算到大的

import java.util.Scanner;
public class Main {
    /*
     * 没有用递归,每次从小于它的素数开始往前算和,看是否有相等的
     */
    public static final int MAX = 10020;
    private static boolean[] com = new boolean[MAX];//素数为false

    public static void findPrime() {
        for (int i = 2; i * i <= MAX; i++) {
            if (!com[i]) {
                for (int j = 2 * i; j < MAX; j += i) {
                    com[j] = true;
                }
            }
        }
    }

    public static void main(String[] args) {
        findPrime();
        Scanner sc = new Scanner(System.in);
        int num, sum = 0, count = 0;
        while ((num = sc.nextInt()) != 0) {
            for (int i = num; i > 1; i--) {
                if(!com[i]){
                    for (int j = i; j > 1 && sum < num; j--) {
                        if (!com[j])
                            sum += j;
                    }
                    if (sum == num)
                        count++;
                    sum = 0;
                }
            }
            System.out.println(count);
            count = 0;
        }
    }
         
}

还看到好多人讨论说可以事先通过把连续素数相加,然后用一个数组来存放每个数的表示方式个数,然后自己又写了下

import java.util.Arrays;
import java.util.Scanner;
public class Main {
    /*
     * 通过连续素数相加,事先算出所有数的表示方式次数,存在数组中
     */
    private static int[] primeSet = new int[1250];
    private static int[] countSet = new int[10020];
        
    public static void findPrime(){
        boolean flag;
        primeSet[0] = 2;
        int c = 1;
        for(int i = 3; i <= 10020; i += 2){
            flag = true;
            for(int j = 3; j*j <= i; j += 2){
                if(i % j == 0){
                flag = false;
                break;
                }
            }
            if(flag)
                primeSet[c++]=i;
        }
        //前60多个相加就已超过10000
        int sum;
        for(int i = 1; i < 70; i++){
            for(int j = 0; j < primeSet.length && primeSet[j] !=0; j++){
                sum = 0;
                for(int k = 0; k < i; k++){
                    sum += primeSet[j+k];
                }
                if(sum < 10020)
                    countSet[sum]++;
                else 
                    break;
            }
        }
    }   

    public static void main(String[] args) {
        findPrime();
        Scanner sc = new Scanner(System.in);
        int num;
        while ((num = sc.nextInt()) != 0) {   
            System.out.println(countSet[num]);            
        }
    }
         
}

 

posted @ 2013-05-09 15:30  sillypudding  阅读(159)  评论(0编辑  收藏  举报