たいちっち

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

【Java】Map(A - Saturday)

解いた問題

AtCoderの「A - Saturday」

提出した回答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String S = sc.next();
        sc.close();
        Map map = new HashMap<>();
        map.put("Monday", 5);
        map.put("Tuesday", 4);
        map.put("Wednesday", 3);
        map.put("Thursday", 2);
        map.put("Friday", 1);
        System.out.println(map.get(S));
    }
}

if文を使って条件分岐をしても良かったけれど、Mapにしてみた。
読みやすくはある(気がする)。

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

 

おわり。。

 

【Java】数値をSetに格納する(A - Five Integers)

解いた問題

AtCoderの「A - Five Integers」

提出した回答
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        Set set = new HashSet();
        for (int i = 0; i < 5; i++) {
            set.add(sc.nextInt());
        }
        System.out.println(set.size());
        sc.close();
    }
}

重複を許さずに格納したいのでSetを使用した。Setの要素数はsize()で取得する。

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

 

おわり。。

【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問題を解く
  • タイミング合う回のコンテストに参加する

 

おわり。。

【Java】Setに指定要素が含まれるかを確認する(B - 81)

解いた問題

AtCoderの「B - 81」

 

提出した回答
import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        sc.close();
        Set set = new HashSet();
        for (int i = 1; i <= 9; i++) {
            for (int j = 1; j <= 9; j++) {
                set.add(i * j);
            }
        }
        if (set.contains(N)) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }
    }
}

for文の中でNとの数値比較(等しい値があればTrue)とすることも出来たがあえてしなかった。
九九の結果をSetの中に入れて、与えられたNがSetの中に存在するかチェックした。

HashSetの

contains(Object o)
指定された要素がセットに含まれている場合にtrueを返します。

を使用している。

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

 

おわり。。

 

 

 

【Java】二重のfor文(B - Cakes and Donuts)

解いた問題

AtCoderの「B - Cakes and Donuts」

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

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

        boolean flag = false;
        for (int i = 0; i <= N/4; i++) {
            for (int j = 0; j <= N/7; j++) {
                if (N == ((i * 4) + (j * 7))) {
                    flag = true;
                    break;
                }
            }
        }
        if (flag) {
            System.out.println("Yes");
        } else {
            System.out.println("No");
        }
    }
}

for文を二重にしただけ。Nが100以下だったのでi,jの条件を100にしても良いかもしれない。

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

 

おわり。。

【Java】入力された値の足し合わせ(B - Bitter Alchemy)

解いた問題

AtCoderの「B - Bitter Alchemy」

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

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int N = sc.nextInt();
        int X = sc.nextInt();
        int minimum_m = 0;
        int sum = 0; //ドーナツ1個ずつ作成時の重さの合計
        for (int i = 0; i < N; i++) {
            int tmp = sc.nextInt();
            sum += tmp;
            if (i == 0) {
                minimum_m = tmp;
                continue;
            }
            //最小を入れ替え
            if (tmp < minimum_m) {
                minimum_m = tmp;
            }
        }
        //この時点でドーナツを1個ずつ、合計N個を、作成している
        //必要な素が最小のドーナツを可能な限り作る
        //
        System.out.println(N + (X - sum) / minimum_m);
        sc.close();
    }
}

最小の値を求める方法として、配列にしてCollectionsやstreamの使用を考えたが、for文の中でシンプルに実装できそうだったので使用しなかった。

全ドーナツを1個ずつ作成し、残ったお菓子の素で最も少ない量の素で作成できるドーナツだけを作成する。
競プロの問題文に少し慣れた気がして嬉しかった。

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

 

おわり。。

 

【Java】文字列の前・後から文字を取得(B - A to Z String)

解いた問題

AtCoderの「B - A to Z String」

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

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String S = sc.next();
        sc.close();

        int num_a = 0;//Aが先頭から何番目か
        for (int i = 0; i < S.length(); i++) {
            int tmp = S.charAt(i);
            if (tmp == 'A') {
                num_a = i+1;
                break;
            }
        }

        int num_z = 0;//Zが先頭から何番目か
        for (int i = S.length()-1; 0 < i; i--) {
            int tmp = S.charAt(i);
            if (tmp == 'Z') {
                num_z = i+1;
                break;
            }
        }

        System.out.println(num_z - num_a +1);
    }
}

Aは前から、Zは後ろから数えて、それぞれ1番初めにヒットした位置を記録し、差を取った。

for文は1つにまとめることができそうだが、こちらの方が処理が見やすく、まとめても計算量はあまり変わらない(と思う2N→N?)ので、上記で提出した。

TODO
  • 他のA,B問題を解く

 

おわり。。