Prime Solutions
以下是一段中学时代的惨痛回忆…每当学到排列组合的单元时,最痛苦的不是分析题目,也不是带错公式或计算错误,而是所谓的「苦工题」,以下这题是个例子:
给定正整数N与S,求出方程式(1)的所有质数解(全为质数)。
遇到这题,通常只能硬着头皮将每一组以「土法炼钢」的方式一一列出,然而到了大学修过程式设计与演算法课,俾使我们能在电脑上撰写程式轻松解决此问题。
INPUT
第一行一样为测资个数
每一行输入正整数与正整数,N与S之间相隔一个空白键。
(提示: 计算之前先考虑方程式有没有解可以加速程式执行。)
OUTPUT
N个质数相加刚好等於S有哪些可能的组合,质数可以重复,但请由小到大排列,若无解(例如100个质数相加等於23无解)则输出0,解可能不只一组,若有多组解时,靠左边的数字较小的那组解则优先输出,请参照SAMPLE OUTPUT。每一笔测资的输出之间也换一行。
SAMPLE INPUT
4
2 5
100 23
3 8
4 25
SAMPLE OUTPUT
2 3
0
2 3 3
2 2 2 19
2 3 3 17
2 3 7 13
2 5 5 13
2 5 7 11
答案
import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Scanner; import java.util.Stack; public class Prime { static List<Integer> primeList = new ArrayList<Integer>(); static List<Integer> starttList = new ArrayList<Integer>(); static List<Integer[]> engtList = new ArrayList<Integer[]>(); static Integer[] iArr ; static boolean flage; //static int a; static int size; static Stack<Integer> stack = new Stack<Integer>(); static Stack<Integer> stackResult = new Stack<Integer>(); public static void main(String[] args) { Scanner scan = new Scanner(System.in); int z = scan.nextInt(); while(z>0){ flage = false; stack.clear(); stackResult.clear(); iArr =null; primeList =new ArrayList<Integer>(); engtList = new ArrayList<Integer[]>(); // System.out.println("请输入您要结果的size:"); size = scan.nextInt(); // System.out.println("请输入您要结果数为:"); int num = scan.nextInt(); for(int i=2;i<=num;i++){ if(isPrime(i)){ primeList.add(i); } } iArr = primeList.toArray(new Integer[0]); sort(iArr); Calc(num, iArr); int j=0; if(!flage){ System.out.println(j); } z--; Comparator<Integer[]> comparator = new Comparator<Integer[]>() { public int compare(Integer[] s1, Integer[] s2) { for(int i=0;i<s1.length;i++){ if(s1[i]!=s2[i]){ return s1[i]-s2[i]; } } return 1; } }; //这里就会自动根据规则进行排序 Collections.sort(engtList,comparator); for(int i=0;i<engtList.size();i++){ Integer[] stu=engtList.get(i); for(int ii:stu){ System.out.print(ii+" "); } System.out.println(); } if(z>0){ System.out.println(); } } } private static void Calc(int a,Integer[] iArr) { for (int i = 0; i < iArr.length; i++) { if (iArr[i] == a && size==1) { //输出这个数 System.out.println(iArr[i]); flage=true; continue; } // else if (iArr[i] > a) // { // continue; // } if (iArr[i] > a) { continue; } stack.clear(); stack.push(iArr[i]); Func(i, a - iArr[i]); } } private static void Func(int i, int iValue) { for (int j = i ; j < iArr.length; j++) { if (iArr[j] > iValue) { continue; } else if (iValue == iArr[j]) { stack.push(iArr[j]); //输出stack 这一步略.. if(stack.size()==size){ iteratorThroughIterator(stack); } stack.pop(); } else if (iValue > iArr[j]) { stack.push(iArr[j]); Func(j, iValue - iArr[j]); stack.pop(); } } } /** * 通过迭代器遍历Stack */ public static void iteratorThroughIterator(List list) { Integer val = null; for(Iterator iter = list.iterator(); iter.hasNext(); ) { val = (Integer) iter.next(); stackResult.push(val); // System.out.print(val+" "); } // System.out.println(); playResult(stackResult); stackResult.clear(); } /** * 通过迭代器遍历Stack */ public static void playResult(Stack stack) { flage = true; while(!stack.empty()){ starttList.add((Integer) stack.pop()); } Integer[] a= starttList.toArray(new Integer[0]); starttList.clear(); engtList.add(a.clone()); a=null; // System.out.println(); } public static boolean isPrime(int num){ for (int i = 2; i < num; i++) {//运行效率不高 if ((num % i) == 0) { return false; } } return true; }
public static void sort(Integer[] iArr){ for (int i = 0; i < iArr.length -1; i++){ for(int j = 0 ;j < iArr.length - i - 1; j++){ if(iArr[j] < iArr[j + 1]){ int temp = iArr[j]; iArr[j] = iArr[j + 1]; iArr[j + 1] = temp; } } } } }