首页 > 专题系列 > Java解POJ > POJ 3132 Sum of Different Primes [解题报告] Java
2013
11-12

POJ 3132 Sum of Different Primes [解题报告] Java

Sum of Different Primes

问题描述 :

A positive integer may be expressed as a sum of different prime numbers (primes), in one way or another. Given two positive integers n and k, you should count the number of ways to express n as a sum of k different primes. Here, two ways are considered to be the same if they sum up the same set of the primes. For example, 8 can be expressed as 3 + 5 and 5 + 3 but the are not distinguished.

When n and k are 24 and 3 respectively, the answer is two because there are two sets {2, 3, 19} and {2, 5, 17} whose sums are equal to 24. There are not other sets of three primes that sum up to 24. For n = 24 and k = 2, the answer is three, because there are three sets {5, 19}, {7, 17} and {11, 13}. For n = 2 and k = 1, the answer is one, because there is only one set {2} whose sum is 2. For n = 1 and k = 1, the answer is zero. As 1 is not a prime, you shouldn’t count {1}. For n = 4 and k = 2, the answer is zero, because there are no sets of two different primes whose sums are 4.

Your job is to write a program that reports the number of such ways for the given n and k.

输入:

The input is a sequence of datasets followed by a line containing two zeros separated by a space. A dataset is a line containing two positive integers n and k separated by a space. You may assume that n ≤ 1120 and k ≤ 14.

输出:

The output should be composed of lines, each corresponding to an input dataset. An output line should contain one non-negative integer indicating the number of the ways for n and k specified in the corresponding dataset. You may assume that it is less than 231.

样例输入:

24 3 
24 2 
2 1 
1 1 
4 2 
18 3 
17 1 
17 3 
17 4 
100 5 
1000 10 
1120 14 
0 0

样例输出:

2 
3 
1 
0 
0 
2 
1 
0 
1 
55 
200102899 
2079324314

解题代码:

//* @author:
import java.io.BufferedInputStream;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    static ArrayList< Integer> primes = Prime.getPrimes(1120);

    public static void main(String[] args) {
        int[][] f = new int[1140][1140];
        Scanner scan = new Scanner(new BufferedInputStream(System.in));
        f[0][0] = 1;
        for (int j = 0; j < primes.size(); j++) {
        for (int i = 14; i >= 1; i--) {
               for (int v = 1120; v > 0; v--) {
                    if (v - primes.get(j) >= 0) {
                        f[i][v] += f[i - 1][v - primes.get(j)];
                    }
                }
            }
        }
        while (scan.hasNext()) {
            int n = scan.nextInt();
            int k = scan.nextInt();
            if (n == 0 && k == 0) {
                break;
            }
            System.out.println(f[k][n]);
        }
    }
}

class Prime {

    public static ArrayList getPrimes(int n) {
        int i, j, k, x, num;
        n++;
        n /= 2;
        int[] b = new int[(n + 1) * 2];
        ArrayList a = new ArrayList();
        a.add(0, 2);
        a.add(1, 3);
        num = 2;
        for (i = 1; i <= 2 * n; i++) {
            b[i] = 0;
        }
        for (i = 3; i <= n; i += 3) {
            for (j = 0; j < 2; j++) {
                x = 2 * (i + j) - 1;
                while (b[x] == 0) {
                    a.add(num++, x);
                    for (k = x; k <= 2 * n; k += x) {
                        b[k] = 1;
                    }
                }
            }
        }
        return a;
    }
}

  1. 在方法1里面:

    //遍历所有的边,计算入度
    for(int i=0; i<V; i++)
    {
    degree = 0;
    for (j = adj .begin(); j != adj .end(); ++j)
    {
    degree[*j]++;
    }
    }

    为什么每遍历一条链表,要首先将每个链表头的顶点的入度置为0呢?
    比如顶点5,若在顶点1、2、3、4的链表中出现过顶点5,那么要增加顶点5的入度,但是在遍历顶点5的链表时,又将顶点5的入度置为0了,那之前的从顶点1234到顶点5的边不是都没了吗?