某财务部门结账时发现总金额不对头。很可能是从明细上漏掉了某1笔或几笔。如果已知明细账目清单,能通过编程找到漏掉的是哪1笔或几笔吗?
如果有多种可能,则输出所有可能的情况。
我们规定:用户输入的第一行是:有错的总金额。
接下来是一个整数n,表示下面将要输入的明细账目的条数。
再接下来是n行整数,分别表示每笔账目的金额。
要求程序输出:所有可能漏掉的金额组合。每个情况1行。金额按照从小到大排列,中间用空格分开。
比如:
用户输入:
6
5
3
2
4
3
1
表明:有错的总金额是6;明细共有5笔。
此时,程序应该输出:
1 3 3
1 2 4
3 4
为了方便,不妨假设所有的金额都是整数;每笔金额不超过1000,金额的明细条数不超过100。

解决方案 »

  1.   

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Scanner;public class TotalMoney {public static void money(int total, List<Integer> list1, List<Integer> list2, int sum, List list){ //list1 为上次剩下的 list2为装入的
    if(sum==total){
    Collections.sort(list2);
      if(list.isEmpty()){
      for(int k=0; k<list2.size(); k++){
      list.add(list2.get(k));
      }
      for(int k=0; k<list2.size(); k++){
      System.out.print(list2.get(k)+" ");
      }
      System.out.println();
      }
      else{
      boolean flag = true;
      
      for(int k=0; k<list.size(); k++){
      if(list.get(k)==list2.get(0))
      if(list.subList(k, list2.size()+k).equals(list2))
      { flag = false;
      break; 
      }
      }
      
      if(flag){
      for(int k=0; k<list2.size(); k++){
      System.out.print(list2.get(k)+" ");
      list.add(list2.get(k));
      }
      System.out.println();
      }
      
      
      }
    }for(int i=0; i<list1.size(); i++){
    List list3 = new ArrayList();
    List list4 = new ArrayList();
    int n = sum;
    if(n<total){
    n+=list1.get(i);for(int m=0; m<list2.size(); m++) //上次的
    list4.add(list2.get(m));list4.add(list1.get(i)); //转入当前的for(int j=0; j<list1.size(); j++){
    if(j>i)
    list3.add(list1.get(j)); 
    }
    money(total, list3, list4, n, list); //递归
    } } }
    public static void main(String[] args) {
    Scanner in = new Scanner(System.in);
    int totalMoney = in.nextInt();
    int count = in.nextInt();
    int sum = 0;
    List<Integer> list1 = new ArrayList();
    List<Integer> list = new ArrayList();
    List<Integer> list2 = new ArrayList();
    while(--count>=0){
    int n = in.nextInt();
    sum +=n;
    list.add(n); 
    }
    int lastMoney = sum-totalMoney;
    money(lastMoney, list, list1, 0, list2);
    }}
      

  2.   


    import java.util.ArrayList;
    import java.util.HashSet;
    import java.util.List;
    import java.util.Set;
    public class TM {
    static int[] array ={6,5,3,2,4,3,1};
    static int totalErrorMoney=0;
    static int totalRightMoney=0;
    static int totalCount =0;
    static List<Integer> elements = new ArrayList<Integer>();

    public static void main(String[] args) {
    Set<List<Integer>> answers=new HashSet<List<Integer>>();
    totalErrorMoney = array[0];
    totalCount = array[1];
    for(int i=2;i<array.length;i++){//把账目排序插入elements中
    if(elements.size()==0){
    elements.add(array[i]);
    totalRightMoney+=array[i];
    }
    else{
    for(int j=0;j<elements.size();j++){
    if(elements.get(j)>=array[i]){
    elements.add(j,array[i]);
    totalRightMoney+=array[i];
    break;
    }
    else{
    if(j==elements.size()-1){
    elements.add(array[i]);
    totalRightMoney+=array[i];
    break;
    }
    }
    }

    }
    }
    int[] flags=new int[elements.size()];
    for(int z=0;z<flags.length;z++){//标记数组初始化
    flags[z]=0;
    }
    int result = totalRightMoney-totalErrorMoney;
    System.out.println(elements);
    //模型转化为在list数组中找出若干个数之和为result;
    while(flags[0]<2){//判断是否符合条件
    int temp=0;
    for (int i= 0;i<elements.size();i++){
    temp+=(elements.get(i)*flags[i]);
                }
    if(temp==result){
    //打印出结果
    for (int i= 0;i<flags.length; i++){
    if(flags[i]==1){
    System.out.print(elements.get(i)+" ");
    }
                }
    System.out.println("\n---------------");
    }

    flags[flags.length-1]++; //模拟进位,低位增加
    for (int i=flags.length-1;i >0;i --) { //判断是否发生进位
                    if (flags[i] == 2){//如果某位到达9,则发生进位
                     flags[i] = 0; //进位就是该位置重新赋值为1
                     flags[i-1]++; //该位置的前一位置增加1
                    } else {//如果没有发生进位,后续的也不会再发生了
                        break;//避免无意义的循环,break退出进位判断
                    }
                }
    }
    }
    }
    //结果解释
    [1, 2, 3, 3, 4]
    3 4 
    ---------------
    3 4 
    ---------------
    1 3 3 
    ---------------
    1 2 4 
    ---------------
    //为什么会有2个同样的3,是因为这两个3不是同一对象,你的输入里面有两个3.我还以为是程序重复了。
      

  3.   

    懒得看,用Eclipse步入,自己慢慢看呗~