某财务部门结账时发现总金额不对头。很可能是从明细上漏掉了某1笔或几笔。 如果已知明细账目清单,能通过编程找到漏掉的是哪1笔或几笔吗?

来源:互联网 发布:讯鸟软件 骗局 编辑:程序博客网 时间:2024/04/28 23:45
/* * 某财务部门结账时发现总金额不对头。很可能是从明细上漏掉了某1笔或几笔。 * 如果已知明细账目清单,能通过编程找到漏掉的是哪1笔或几笔吗? * 如果有多种可能,则输出所有可能的情况。 * 我们规定:用户输入的第一行是:有错的总金额。 * 接下来是一个整数n,表示下面将要输入的明细账目的条数。 * 再接下来是n行整数,分别表示每笔账目的金额。 *  * 要求程序输出:所有可能漏掉的金额组合。每个情况1行。金额按照从小到大排列,中间用空格分开。 * 比如: * 用户输入:6532431表明:有错的总金额是6;明细共有5笔。此时,程序应该输出:1 3 31 2 43 4为了方便,不妨假设所有的金额都是整数;每笔金额不超过1000,金额的明细条数不超过100。 */import java.util.ArrayList;import java.util.Arrays;import java.util.Iterator;import java.util.LinkedHashSet;import java.util.List;import java.util.Scanner;import java.util.Set;public class Demo08 {static Set<List<Integer>> sets = new LinkedHashSet<List<Integer>>();// 保存记录// 得到漏掉的总金额public static int sum(int[] d){int leak = 0;for(int i=0;i<d.length;i++){leak += d[i];}return leak;}// 修改b元素+1进位public static void modify(int[] b){b[b.length-1]++;for(int i=b.length-1;i>0;i--){if(b[i]>1){b[i] = 0;b[i-1]++;}}}// 检测b是否全111111...public static boolean check(int[] b){boolean flag = true;for(int i=0;i<b.length;i++){if(b[i]==0){flag = false;break;}}return flag;}public static void calc(int le,int[] d,int[] b){if(check(b)){return;}int sum = 0;for(int i=d.length-1;i>=0;i--){if(b[i]!=0){sum += d[i];}}if(sum==le){List<Integer> lis = new ArrayList();for(int i=0;i<d.length;i++){if(b[i]!=0){lis.add(d[i]);}}sets.add(lis);//lis.clear();}modify(b);calc(le,d,b);}// 输出结果public static void print(){Iterator<List<Integer>> iter = sets.iterator();while(iter.hasNext()){Iterator<Integer> iter2 = iter.next().iterator();while(iter2.hasNext()){System.out.print(iter2.next()+" ");}System.out.println();}}public static void main(String[] args){Scanner scan = new Scanner(System.in);int err = scan.nextInt();int n = scan.nextInt();int[] d = new int[n];for(int i=0;i<n;i++){d[i] = scan.nextInt();}Arrays.sort(d);int le = sum(d) - err;// 得到漏掉的总金额int[] b = new int[d.length];// 初始为全零 作为标记,记录数字是否使用 0为未使用 1为已经使用calc(le,d,b);System.out.println("输出结果:");print();}}
运行结果:
6532431输出结果:3 4 1 3 3 1 2 4 

原创粉丝点击