平安科技在线编程大赛【一份“奇妙”的银行流水】共性问题分析及正确代码分享

csdn高校俱乐部 编程 

CSDN-木水辰

毕业生北京邮电大学

2014年8月,CSDN高校俱乐部、英雄会联合平安科技公司推出在线编程比赛活动,赛题为【一份“奇妙”的银行流水】。

在历时一个月的比赛过程中,2000+人参与答题挑战,而通过者仅22人,与题目3星级的难度系数形成了鲜明的反差。


由于比赛规则为第一次挑战并且通过才具备获奖评选资格,绝大部分参与者在思路正确的情况下,由于对细节的疏忽而挑战失败。

问题主要体现在:

1、读题不认真,忽略题目要求的“第一行输入输出标头”;
2、没有注意题目描述中,输入输出要求保留小数点后两位

为此,俱乐部在此公布题目详情,并贴出标准代码和雅虎刷题狂人曹鹏博士的解题代码各一份。供同学们学习探讨。点击下列标签直接阅读:

  赛题描述                      标准代码                    雅虎刷题狂人曹鹏博士解题代码 


 

平安科技在线编程大赛赛题:一份“奇妙”的银行流水

题目详情
一份银行流水数据,因打印模糊导致部分金额不清楚。                  
收入、支出、余额满足以下3条规则:              
1、收入、支出、余额三列都是数字            
2、同一行收入和支出的值不能同时为非零值            
3、第N-1行余额(+第N行收入或-第N行支出)=第N行余额  
程序语言: java
请按照规则编写算法,修复不清楚的值

输入描述:
输入数据最多25行,每行都包含四个数据,分别是:数据编号,收入、支出、余额,模糊的数据以?表示,它们之间以;隔开。
以文件结尾。第一组数据为初始数据值,收入、支出、余额数据保留2位小数。 输入输出第一行均为表头“流水记录ID;收入;支出;余额”。
输出描述:
以输入的数据顺序输出修复后的数据。

答题说明
输入样例:
流水记录ID;收入;支出;余额
1;0.00;51.90;1945.45    
2;0.00;1000.00;?
输出样例:
流水记录ID;收入;支出;余额
1;0.00;51.90;1945.45
2;0.00;1000.00;945.45


标准代码展示

import java.io.FileWriter;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class TestBankFlow {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
//        FileReader fr = null;
//        BufferedReader br= null;
//        FileWriter fw = null;
        Scanner sc=new Scanner(System.in);
      try {
          List<Map<String,String>> list = new ArrayList<Map<String,String>>();
//          fr=new FileReader("java.in");        
//          br=new BufferedReader(fr);
          String line="";        
          String[] arrs=null;       
          while (sc.hasNextLine()) {
              line = sc.nextLine();
              if(line == null || "".equals(line.trim()))
                  break;
              arrs=line.split(";"); 
              Map<String,String> map = new HashMap<String,String>();
              map.put("key0", arrs[0].trim());
              map.put("key1", arrs[1].trim());
              map.put("key2", arrs[2].trim());
              map.put("key3", arrs[3].trim());
//              System.out.println(arrs[0].trim() + " : " + arrs[1].trim() + " : " + arrs[2].trim()+ " : " + arrs[3].trim());   
              list.add(map);
          }    
          modify(list);
//          fw=new FileWriter("java.out");
          for(Map<String,String> t:list){
             System.out.println(t.get("key0")+";"+t.get("key1")+";"+t.get("key2")+";"+t.get("key3"));
          }
    } catch (Exception e) {
        e.printStackTrace();
    }finally{
//        try {
//            br.close();
//            fr.close();
//            fw.close();
//        } catch (IOException e) {
//            // TODO Auto-generated catch block
//            e.printStackTrace();
//        }       
         
    }
 }
 public    static void modify(List<Map<String,String>> list){
        for(int i= 2;i<list.size();i++){
            Map<String,String> map = list.get(i);
            Map<String,String> mapBefore = list.get(i-1);
            if("?".equals(map.get("key1"))||"?".equals(map.get("key2"))){
                BigDecimal tmp = getSubtractValue(map.get("key3"),mapBefore.get("key3"));
                if(tmp.intValue()<0){
                    map.put("key1", "0.00");
                    map.put("key2", tmp.abs().toString());
                }else{
                    map.put("key2", "0.00");
                    map.put("key1", tmp.abs().toString());
                }
            }
            if("?".equals(map.get("key3")) && !"0.00".equals(map.get("key1"))){ 
                BigDecimal tmp = getAddValue(map.get("key1"),mapBefore.get("key3"));
               map.put("key3", tmp.toString());
                 
            }
            if("?".equals(map.get("key3")) &&!"0.00".equals(map.get("key2"))){ 
                BigDecimal tmp = getSubtractValue(mapBefore.get("key3"),map.get("key2"));
               map.put("key3", tmp.toString());
                 
            }
            if("?".equals(map.get("key3")) &&"0.00".equals(map.get("key2"))&&"0.00".equals(map.get("key1"))){ 
//                BigDecimal tmp = getSubtractValue(mapBefore.get("key3"),map.get("key2"));
               map.put("key3", mapBefore.get("key3"));
                 
            }
//            System.out.println(map.get("key0"));   
            
            
//           if("key1".equals(findX(map))){
//                    mapNext.put("key1", getValue(mapNext.get("key3"),map.get("key3")));
//                }
//                if("key2".equals(findX(map))){
//                    mapNext.put("key2", getValue(mapNext.get("key3"),map.get("key3")));
//                }
//                if("key3".equals(findX(map))&&"0".equals(mapNext.get("key1"))){
//                    mapNext.put("key3", getValue(mapNext.get("key3"),mapNext.get("key2")));
//                }
//                if("key3".equals(findX(map))&&"0".equals(mapNext.get("key2"))){
//                    mapNext.put("key3", getValue(mapNext.get("key3"),mapNext.get("key1")));
//                }
//             
        }
    }
 public    static BigDecimal getSubtractValue(String v1,String v2){
     BigDecimal b1 = new BigDecimal(v1);
     BigDecimal b2 = new BigDecimal(v2);
     return b1.subtract(b2);
     
 }
 public    static BigDecimal getAddValue(String v1,String v2){
     BigDecimal b1 = new BigDecimal(v1);
     BigDecimal b2 = new BigDecimal(v2);
     return b1.add(b2);
     
 }
  
}


雅虎刷题狂人曹鹏博士代码展示

import java.util.*;
public class solution {
    public static void main(String args[]) {
        ArrayList<long[]> tempData = new ArrayList<long[]>();
          Scanner scanner = new Scanner(System.in);
        boolean first = true;
        while (scanner.hasNext()) {
            String line = scanner.nextLine();
            if (first) {
                first = false;
                System.out.println(line);  // the first line is title
            }
            else {
                String[] str = line.split(";");
                if (str.length != 4) {
                    System.err.println("The number of the fields is not 4!");
                    return;
                }
                long [] number = new long [str.length];
                for (int i = 0; i < str.length; ++i) {  //use long to denote double that would preserve the accuracy
                    number[i] = "?".equals(str[i].trim())?(-1L):((long) (Double.parseDouble(str[i]) * 100. + .5));
                }
                tempData.add(number);
            }
        }
        long [][] data = tempData.toArray(new long[tempData.size()][]);
        for (int i = 1; i < data.length; ++i) {
            // 0..i - 1 data[.][3] are all known try to find data[i][3]
            if (data[i][1] > 0) {
                data[i][2] = 0;
                data[i][3] = data[i - 1][3] + data[i][1];
            }
            else if (data[i][2] > 0) {
                data[i][1] = 0;
                data[i][3] = data[i - 1][3] - data[i][2];
            }
            else if ((data[i][1] == 0) && (data[i][2] == 0)) {
                data[i][3] = data[i - 1][3];
            }                
            else if (data[i][3] >= 0) {
                if (data[i][3] >= data[i - 1][3]) {
                    data[i][1] = data[i][3] - data[i - 1][3];
                    data[i][2] = 0;
                }
                else {
                    data[i][1] = 0;
                    data[i][2] = data[i - 1][3] - data[i][3];
                }
            }
            else {
                int j;
                // find the next one to calculate this one
                   for (j = i; (j < data.length) && (data[j][3] < 0); ++j) 
                ;
                if (j >= data.length) { 
                    System.err.println("The solution is not unique!");
                    return;
                }
                for (int k = j; k >= i; --k) {
                    if (data[k][1] > 0) {
                        data[k][2] = 0;
                        data[k - 1][3] = data[k][3] - data[k][1];
                    }
                    else if (data[k][2] > 0) {
                        data[k][1] = 0;
                        data[k - 1][3] = data[k][3] + data[k][2];
                    }
                    else if ((data[k][1] == 0) && (data[k][2] == 0)) {
                        data[k - 1][3] = data[k][3];
                    }        
                    else if (data[k - 1][3] >= 0) {
                        if (data[k - 1][3] <= data[k][3]) {
                            data[k][1] = data[k][3] - data[k - 1][3];
                            data[k][2] = 0;
                        }
                        else {
                            data[k][1] = 0;
                            data[k][2] = data[k - 1][3] - data[k][3];
                        }
                      }    
                   }
                i = j;     
            }
        }
        for (int i = 0; i < data.length; ++i) {
            System.out.print(data[i][0] / 100);
            for (int j = 1; j < 4; ++j) {
                if (data[i][j] < 0) { // the data is wrong/not unique
                    System.err.println("The data is wrong!");
                    return;
                }
                System.out.print(";" + String.format("%.2f", data[i][j] / 100.0));
            }
               System.out.println();
        }
     }   
}

创建
2014-11-17
浏览
25614次
最新回复
2014-12-22
回复
3
0

waklok

毕业生清华大学

新人报道

2014年11月26日 22:28:08

说了是兔子啦

毕业生扬州大学

汗~原来是指表头……“第一行输入输出标头

2014年12月04日 09:15:24

最爱麦丽素

毕业生盐城工学院

我的代码不知道短了多少。

2014年12月22日 17:56:24
Top_arrow