LoginSignup
1
0

More than 1 year has passed since last update.

Atcoder 競プロ典型90問 【004 Cross Sum】 Javaで詰まった話

Last updated at Posted at 2022-11-02

こんにちは、Kuniです。現在Javaを学習中で、Atcoderでコーディング力を高めているところです。
そこで競プロ典型90問 004-CrossSumにおいて、TLEが続いてしまい詰まったので、共有します。

TLEのプログラムとACのプログラム

TLEとなってしまったプログラム
import java.util.*;

public class Main {
    public static void main(String[] args){
        //標準入力受け取り準備
      Scanner scanner = new Scanner(System.in);
 
      //Intで読み込み
      int H = scanner.nextInt();
      int W = scanner.nextInt();
      
      //配列定義&格納
      int[][] number = new int[H][W];
      for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
          number[i][j] = scanner.nextInt();
        }
      }
      scanner.close();
 
      //行と列の合計値計算
      int[] sum_line = new int[H];
      int[] sum_row = new int[W];
      for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
          sum_line[i] += number[i][j];
          sum_row[j] += number[i][j];
        }
      }
 
      //結果格納配列
      int[][] result = new int[H][W];
      for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
          result[i][j] = sum_line[i] + sum_row[j] - number[i][j];
          System.out.printf("%d"+" ", result[i][j]);
        }
        System.out.printf("\n");
      }
    }
}
ACとなったプログラム
import java.util.Scanner;

public class Main { //クラス名はMain
    public static void main(String[] args) {

      //標準入力受け取り準備
      Scanner scanner = new Scanner(System.in);

      //Intで読み込み
      int H = Integer.parseInt(scanner.next());
      int W = Integer.parseInt(scanner.next());
      
      //配列格納
      int[][] number = new int[H][W];
      for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
          number[i][j] = Integer.parseInt(scanner.next());
        }
      }
      scanner.close();

      //行と列の合計値計算
      int[] sum_line = new int[H];
      int[] sum_row = new int[W];
      for(int i = 0; i < H; i++){
        for(int j = 0; j < W; j++){
          sum_line[i] += number[i][j];
          sum_row[j] += number[i][j];
        }
      }

      //結果格納配列
      for(int i = 0; i < H; i++){
        StringBuilder sb = new StringBuilder();
        for(int j = 0; j < W; j++){
          if(j != 0){
            sb.append(" ");
          }
          sb.append(sum_line[i] + sum_row[j] - number[i][j]);
        }
        System.out.println(sb.toString());
      }
    }
}

TLEとなっていた原因

 Javaでは、プログラムを実行するためにVMが存在しているそうですが、変数を保存するための宣言で値を保存しておくためのヒープを確保します。ループを使ってどんどんと値を入れていくような処理をすると、ヒープ領域が増えていってしまい、処理速度の低下に繋がるそうです。
 TLEが発生していたプログラムはこのことが原因で処理速度が低下し、設定時間内にプログラムを終わらせることができませんでした。
 そこでこの問題を解決するために利用するのが、StringBuilderクラスです。

StringBuilderクラスとは

 このクラスは文字列操作を行うことができます。その中でString型はimmutableなオブジェクトですが、StringBuilderはmutableなオブジェクトで、元の文字列を書き換えることができます。今回の問題に対しては文字列を結合するために利用します。
 プログラム内ではStringBuilderのインスタンスを生成し、appendメソッドを利用してインスタンス変数に値を追加します。最後の出力の際にはテキストとして出力を行っています。

 参考になれば嬉しいです!!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0