在CodeChef中获取TLE并需要改进代码

时间:2014-10-02 17:18:22

标签: java

我正在尝试解决 CodeChef 的练习题。在这个问题中我们给出N个数字A i ... A n 我们首先必须对数字进行排序(升序),然后从中添加备用数字最后显示每个测试用例的输出,测试用例有2个部分:
1>约束:
 1≤Ai≤10 9
1≤N≤1000

2 - ;限制条件:
1≤Ai≤10 9
1≤N≤10 5
您可以看到完整的问题here 问题的第一部分是成功提交,但第二部分显示 NZEC ,因为我使用long来添加这些数字(超出该范围)。所以我决定使用Strings来添加我的数字就是方法:

public static String myStringWayToAdd(String first , String second){
    String temp = "";
    if(first.length() < second.length()){
     temp = first;
     first = second;
     second = temp;
    }
     temp = "";
     int carry = 0;
     for(int i=1;i<=first.length();++i){
        if(i <= second.length()){
          carry += Integer.parseInt(first.charAt(first.length()-i)+"") + Integer.parseInt(second.charAt(second.length()-i)+"");
        }
        else{
         carry += Integer.parseInt(first.charAt(first.length()-i)+"");
        }
     temp += carry%10;
     carry = carry/10;
     }
     if(carry != 0)
     temp += carry;
     StringBuilder myResult = new StringBuilder(temp);
    return(myResult.reverse().toString());
 }

但现在它显示 TLE(时间限制过期),所以我想使用BigInteger(我不是很了解但我看到了一些教程):

BigInteger big = new BigInteger("0");
big = big.add(BigInteger.valueOf(mySort.get(j)));  //for addition and mySort is my ArrayList

但是给了我NZEC 我不知道为什么我现在想要使用double变量,但是也存在问题,因为双倍数字将以指数值的形式出现,如:
{<1}} 不会机器接受,那么解决这个问题并没有获得任何时间限制到期有什么好办法吗?
任何帮助将非常感激。先感谢您。

<小时/> 编辑1:
我将baxck变量更改为long并运行,这次奇怪地我得到 TLE 这里是我的代码:

1.243536E15

这是我提交的Link。我可以在代码中优化任何内容吗?

2 个答案:

答案 0 :(得分:1)

  1. 所有数字的总和最多为10^9 * 10^5 = 10^14。它足够小,可以放入long。无需使用BigInteger

  2. java.util.Scanner存在性能问题。您可以实施自定义扫描程序(使用BufferedReader)来加速代码。

  3. 以下是我对扫描仪的实现:

    import java.io.*;
    import java.util.StringTokenizer;
    
    public class FastScanner {
        private BufferedReader reader;
        private StringTokenizer tokenizer;
    
        public FastScanner(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream));
        }
    
        public String next() throws IOException {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                String line = reader.readLine();
                if (line == null)
                    throw new IOException();
                tokenizer = new StringTokenizer(line);
            }
            return tokenizer.nextToken();
        }
    
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
    
        public void close() {
            try {
                reader.close();
            } catch (IOException e) {
                //ignore
            }
        }
    }
    

答案 1 :(得分:0)

我在我的程序中做了一些更改,在提交了大约20次之后,全部接受得到了很大的缓解,这是我的新代码:

import java.util.Scanner;
import java.util.ArrayList;
import java.util.Collections;
class CFEA{
  public static void main(String[] s){
    Scanner scan = new Scanner(System.in);
    byte testCases = Byte.parseByte(scan.nextLine());   //used byte for test cases instead of int
    for(int i = 0 ; i<testCases;++i){
     long sum = 0;
     //BigInteger big = new BigInteger("0");
     ArrayList<Integer> mySort = new ArrayList<Integer>();
     int n = Integer.parseInt(scan.nextLine());
     String input = scan.nextLine();
     String[] my = input.split(" ");
      for(String myString : my){
       mySort.add(Integer.parseInt(myString));
      }
     Collections.sort(mySort);
      for(int j = mySort.size()-1 ; j >= 0 ; j=j-2){
         sum += mySort.get(j);
      }
     System.out.println(sum);
    }
  }
}

我认为主要的反派是我正在扫描整数N次,如下所示:

for(int j = 1 ; j <= n ; ++j){
       mySort.add(scan.nextInt()); 
      }

当N是100000之类的东西时,这真的会减慢它。所以我使用1个字符串表示完整的行,然后使用split方法将其拆分为整数:

String input = scan.nextLine();  //only 1 Scanner
     String[] my = input.split(" ");
      for(String myString : my){
       mySort.add(Integer.parseInt(myString));
      }

虽然我的代码已经提交,但我仍然认为还有进一步的优化范围,所以如果你有更好的东西请回答