未透过的1011——堆栈方式
未通过的1011——堆栈方式
import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Scanner; import java.util.Stack; public class Main { public static void main(String[] args) { new Main(); } public Main() { Scanner s = new Scanner(System.in); while (s.hasNextInt()) { // 获得长度 int count = s.nextInt(); if (count == 0) { break; } int[] nums = new int[count]; // 获得数组、和 int sum = 0; for (int i = 0; i < count; i++) { int num = s.nextInt(); sum += num; nums[i] = num; } // 排序 Arrays.sort(nums); // 最大值 int max = nums[count - 1]; // 遍历可能的结果 for (int i : getList(sum)) { if (max <= i) { if (exec(nums, i, sum)) { break; } } } } s.close(); } public boolean exec(int[] nums, int l, int sum) { // 数组长度 int size = nums.length; // 可变总长 int s = l; // 堆栈 Stack<Integer> stack = new Stack<Integer>(); // 标记 boolean[] flags = new boolean[size]; // 初始化i int i = size - 1; while (true) { for (; i >= 0; i--) { // 如果剩余可用数之和不够,pass if (!isEnough(nums, flags, i, s)) { break; } // 如果当前数不可用,pass if (flags[i]) { continue; } int n = nums[i]; // 如果大于和,pass if (n > s) { continue; } // 如果跟上一个可用数一样,pass if (i + 1 < size && n == nums[i + 1] && !flags[i + 1]) { continue; } // 标记已用 flags[i] = true; // 进栈 stack.push(i); // 从和中减掉 s -= n; if (s == 0) { sum -= l; // 判断是否全部用尽 if (sum == 0) { System.out.println(l); return true; } else { // 再次轮回匹配剩余的可用数 i = size - 1; s = l; } } } // 可用数用尽,当前匹配也没成功 // 恢复最后的数 int top = stack.pop(); flags[top] = false; s += nums[top]; if (s == l) { sum += l; if (!stack.isEmpty()) { top = stack.pop(); flags[top] = false; s = nums[top]; } } // 如果是边缘,恢复倒数第二个数 if (top == 0) { top = stack.pop(); flags[top] = false; s += nums[top]; } // 如果弹出的数是栈中最后一个,匹配失败 if (top == size - 1) { return false; } // 从下一个可用数开始 i = top - 1; } } // 判断剩余可用数之和是否够 public boolean isEnough(int[] nums, boolean[] flags, int begin, int sum) { for (int i = begin; i >= 0; i--) { if (!flags[i]) { sum -= nums[i]; if (sum <= 0) { return true; } } } return false; } // 获得可能的结果List public List<Integer> getList(int n) { List<Integer> list = new ArrayList<Integer>(); for (int i = 1; i <= Math.sqrt(n); i++) { if (n % i == 0) { list.add(i); if (i * i != n) { list.add(n / i); } } } Collections.sort(list); return list; } }