たいちっち

競技プログラミングをしています

【Java】二重の配列(B - Good Distance)

解いた問題

AtCoderの「B - Good Distance」

これまでで1番時間が掛かった・・・。

提出した回答
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int D = sc.nextInt();

        //二重の配列を作成する
        List list = new ArrayList();//外側のリスト,要素はN個
        for (int i = 0; i < N; i++) {
            List listTmp = new ArrayList();//内側のリスト,要素はD個
            for (int j = 0; j < D; j++) {
                listTmp.add(sc.nextInt());//X1,X2,,,XDのような1行を取得、リストに格納
            }
            list.add(listTmp);
        }
        //全部を比較計算する必要はない
        //1番目の点では、他の全ての点と比較(N-1回)
        //2番目の点では、1番目の点を除く、他の全ての点と比較(N-2回)
        //N-1番目の点では、「N-1とN」を比較(1回)
        //N番目の点では、比較終了している(0回)
        int counter = 0;
        for (int i = 0; i < N; i++) {
            List<Integer> list_i = (List) list.get(i);
            for (int j = i+1; j < N; j++) {
                List<Integer> list_j = (List) list.get(j);
                //点と点の距離を計算する
                double sum = 0;
                for (int k = 0; k < D; k++) {
                    int tmp = list_i.get(k) - list_j.get(k);
                    sum += tmp * tmp;
                }
                double result = Math.sqrt(sum);
                if (result == (int) result) {
                    counter += 1;
                }
            }
        }
        System.out.println(counter);
        sc.close();
    }
}
  • 二重の配列の作成方法
  • 整数の判定方法

で悩んだ。
他の方の実装方法を見て勉強する。

二重の配列の作成方法

私は以下のように、外側に1個、内側にN個の配列(各D個の要素を持つ)を作成したかったのでfor文で書いた。

//二重の配列を作成する
        List list = new ArrayList();//外側のリスト,要素はN個
        for (int i = 0; i < N; i++) {
            List listTmp = new ArrayList();//内側のリスト,要素はD個
            for (int j = 0; j < D; j++) {
                listTmp.add(sc.nextInt());//X1,X2,,,XDのような1行を取得、リストに格納
            }
            list.add(listTmp);
        }

 

他の多くの方は、初めから二重の配列を作る形で、以下のように実装されていた。

int[][] list = new int[N][D];
for(int i=0; i<N; i++){ //N列分
    for(int j=0; j<D; j++){ //D行分
        list[i][j] = sc.nextInt();
    }
}

こちらの方が簡単に書けるので、次回以降はこの形式で書きたい。

整数の判定方法

私は平方根の値(result)と、int型にキャストした平方根の値(int result)を比較した。もともとのresultが整数であれば、整数化した値と比べても等しいという方法。

double result = Math.sqrt(sum);
if (result == (int) result) {
    counter += 1;
}

 

他の多くの方は、int型にキャストした値を平方根の値(result)に入れて、もともとの計算結果(sum)と比較する、という処理をしていた。

int result = (int)Math.sqrt(sum);
if(result * result == sum){
    count++;
}

これはあまり差がないのかな?いずれにしてもキャストが必要そうである。

TODO
  • 他のA,B問題を解く
  • タイミング合う回のコンテストに参加する

 

おわり。。