AtCoder (AtCoder Beginners Selection) [PracticeA, ABC086A, ABC081A, ABC081B]

前々からAtCoderに登録はしていましたが、ちゃんとやっていなかったのでチャレンジしてみようと思います。

今回は初心者向けの問題のAtCoder Beginners Selectionやってみたいと思います。問題数があるのでこれは分けて投稿します。

PracticeA – Welcome to AtCoder

https://atcoder.jp/contests/abs/tasks/practice_1

問題概要

入力された3つの数字の和とその後に入力された文字列を連結して出力すると言う問題です。

問題の内容をそのまま載せて良いのか分からないので詳しくはリンク先をみてもらえればと思います。

これは本当に入門の問題で答えのサンプルも記載されている感じです。

作成ソース

言語

Java8 (OpenJDK 1.8.0)

コード

今回のプログラムは以下のようになりました。

import java.util.Scanner;
 
public class Main {
 
    public static void main(String... args) {
 
        try (Scanner input = new Scanner(System.in)) {
            int a = input.nextInt();
            int b = input.nextInt();
            int c = input.nextInt();
            String s = input.next();
            System.out.println((a + b + c) + " " + s);
        }
    }
}

一応、streamを閉じるようにしましたが、別にいらなかったとは思います。

結果

今回の実行結果は以下のようになりました。

  • 実行時間:110 ms
  • メモリ:22356 KB

ABC086A – Product

https://atcoder.jp/contests/abs/tasks/abc086_a

問題概要

入力された2つの数の積が奇数か偶数か判定する問題です。

作成ソース

言語

Java8 (OpenJDK 1.8.0)

コード

以下のように作成しました。特に補足するようなところもないかなと思います。

import java.util.Scanner;
 
public class Main {
 
    public static void main(String... args) {
 
        try (Scanner input = new Scanner(System.in)) {
            int a = input.nextInt();
            int b = input.nextInt();
            int p = a * b;
            System.out.println(p % 2 == 0 ? "Even" : "Odd");
        }
 
    }
 
}

結果

実行結果は以下のようになりました。

  • 実行時間:97 ms
  • メモリ:21844 KB

ABC081A – Placing Marbles

https://atcoder.jp/contests/abs/tasks/abc081_a

問題概要

0か1の数字が続けて3文字入力されるので、その中で1となっている数を返すと言う問題です。

作成ソース

言語

Java8 (OpenJDK 1.8.0)

コード

以下のように作成しました。

import java.util.Scanner;
 
public class Main {
 
    public static void main(String... args) {
 
        try (Scanner input = new Scanner(System.in)) {
            String s = input.next();
            int s1 = s.charAt(0) == '1' ? 1 : 0;
            int s2 = s.charAt(1) == '1' ? 1 : 0;
            int s3 = s.charAt(2) == '1' ? 1 : 0;
            System.out.println(s1 + s2 + s3);
        }
 
    }
 
}

入力された文字列(String)を順番にcharとして見て、それが「1」であればカウントする感じです。

結果

今回の結果は以下のようになりました。

  • 実行時間:89 ms
  • メモリ:21716 KB

ちなみに最初作成したコードはメモリや実行時間が微妙だったので作り直しました。本当に上位の人と比べるとまだまだですが、それなりの数字になったんじゃないかと思います。

ABC081B – Shift only

https://atcoder.jp/contests/abs/tasks/abc081_b

問題概要

N個の整数に対して、全てが偶数であれば2で割るという操作を全てが偶数ではなくなるまで繰り返し、操作を行った回数を返却する問題です。整数の数であるNは最初に入力されます。

作成ソース

言語

Java8 (OpenJDK 1.8.0)

コード

以下のように作成しました。

import java.util.Scanner;
 
public class Main {
 
    public static void main(String... args) {
        try (Scanner input = new Scanner(System.in)) {
            System.out.println(new Main().execute(input));
        }
 
    }
 
    private Object execute(Scanner sc) {
        int[] read = readInput(sc);
 
        int min = Integer.MAX_VALUE;
        for (int i : read) {
            min = Math.min(min, opc(i));
        }
        return min;
 
    }
 
    private int opc(int i) {
        int opc = 0;
        int n = i;
        while (true) {
            if (n % 2 == 0) {
                n = n / 2;
                opc++;
            } else {
                return opc;
            }
        }
    }
 
    private int[] readInput(Scanner sc) {
        int n = sc.nextInt();
        int[] arr = new int[n];
 
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
        }
 
        return arr;
    }
 
}

コード解説

単純に2で割るという操作を全体に対して実施し、それを繰り返しても良いのですが、それだとメモリ消費が多そうだったので、1つずつ処理することにしました。

まず、

    private int opc(int i) {
        int opc = 0;
        int n = i;
        while (true) {
            if (n % 2 == 0) {
                n = n / 2;
                opc++;
            } else {
                return opc;
            }
        }
    }

は入力された数値が最大何回の「2で割る操作」ができるかを判定するメソッドです。
これを以下のように各入力でループして、その最小値を返却するようにしています。

    private Object execute(Scanner sc) {
        int[] read = readInput(sc);
 
        int min = Integer.MAX_VALUE;
        for (int i : read) {
            min = Math.min(min, opc(i));
        }
        return min;
 
    }

以下は入力を読み込む部分で、最初に整数の数Nが入力されるので、その数だけの配列を用意し、そこにその後の入力を順番に入れています。

    private int[] readInput(Scanner sc) {
        int n = sc.nextInt();
        int[] arr = new int[n];
 
        for (int i = 0; i < n; i++) {
            arr[i] = sc.nextInt();
        }
 
        return arr;
    }

普段の実装だとListを使いますが、メモリ消費が少ないintの配列にしています。

結果

今回の結果は以下のようになりました。

  • 実行時間:114 ms
  • メモリ:21844 KB

コメント

タイトルとURLをコピーしました