LoginSignup
0
0

More than 3 years have passed since last update.

AtCoder Beginner Contest 182 参戦記事

Last updated at Posted at 2020-11-08

AtCoder Beginner Contest 182に20分ほど遅れて参戦。
まあ時間通りでも最後まではいけないので、やれることをやる。

A - twiblr

ルール通りフォロー数の上限を計算し、現在のフォロー数を引くだけ。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        try(Scanner s = new Scanner(System.in)){
            System.out.println(s.nextInt() * 2 + 100 - s.nextInt());
        }
    }
}

B - Almost GCD

ユークリッドの互除法で最大公約数求めればいいんじゃないか?と思ったが、例を見て納得。全体での最大公約数が1だとまずいことになる。
となると、それぞれの数を素因数分解して、共通する素因数が多いものを選べばいい…と思ったあたりで気づく。
だったら、最初から全部試し割りしてもさほど変わらなくないか?

import java.util.*;

public class Main {
    public static void main(String[] args) {
        try (Scanner s = new Scanner(System.in)) {
            int n = s.nextInt();
            int[] a = new int[n];
            int max = 0;
            for (int i = 0; i < n; i++) {
                a[i] = s.nextInt();
                max = Math.max(max, a[i]);
            }
            int maxCount = 0;
            int tempK = 0;
            for (int k = 2; k <= max; k++) {
                int count = 0;
                for (int x : a) {
                    if (x % k == 0) {
                        count++;
                    }
                }
                if (count > maxCount) {
                    tempK = k;
                    maxCount = count;
                    if (maxCount == n) {
                        break;
                    }
                }
            }
            System.out.println(tempK);
        }
    }
}

C - To 3

ある数を3で割った余りは、その数の各位の数字の合計を3で割った余りに等しいことを利用。
余りの話は、余りだけで議論できるので、各位に分解して3で割った余りに変換。
ここから場合分けに四苦八苦。合計の余りが0,1,2の時で分けて、と考えていると、あることに気づく。

合計余りが1の場合で、余り1の桁がない場合は、桁を構成しているのが余り0と余り2だけという事になる。
全部の桁が余り0であれば合計余りは0になり、余り2の桁が1つだけなら合計余り2になるはずなので、
少なくとも余り2の桁が2つあることになる。この2つを抜けば、余り0にすることができる。
合計余りが2の場合も同様なので、「桁を探す」処理を除くと、判定が5行で書けた。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        try (Scanner s = new Scanner(System.in)) {
            int[] x = s.next().chars().map(i -> (i - '0') % 3).toArray();
            int r = Arrays.stream(x).sum() % 3;
            System.out.println(remove(x, r));
        }
    }

    private static int remove(int[] x, int r) {
        if (r == 0) return 0;
        if (x.length == 1) return -1;
        if (find(x, r)) return 1;
        if (x.length == 2) return -1;
        return 2;
    }

    private static boolean find(int[] x, int target) {
        for (int a : x) {
            if (a == target){
                return true;
            }
        }
        return false;
    }
}

D - Wandering

最初は愚直にやろうと思った。実行時間的に不安を覚えながら書いていったが、
書いているうちに、累積和の考え方が使えそうだとひらめき、書き直し。
$A_1$~$A_i\,(i=1,2,\dots ,N)$のひとかたまりで、正方向に動ける最大量があるはずなので、
その最大量動いた時の位置を記録し、比較する。
ここでやらかし。数値の範囲からlongにしないとあふれることは認識していたのに、
$A_i$を記録するint配列をそのまま累積和に再利用してしまったため、一回WAになってしまった。
longの配列に作り直してAC。

import java.util.*;

public class Main {
    public static void main(String[] args) {
        try (Scanner s = new Scanner(System.in)) {
            s.nextLine();
            long[] a = Arrays.stream(s.nextLine().split(" "))
                                .mapToLong(Long::parseLong)
                                .toArray();
            long[] max = new long[a.length];
            max[0] = a[0];
            for (int i = 1; i < a.length; i++) {
                a[i] += a[i - 1];
                max[i] = Math.max(max[i - 1], a[i]);
            }


            long maxP = 0;
            long p = 0;
            for (int i = 0; i < a.length; i++) {
                maxP = Math.max(maxP, p + max[i]);
                p += a[i];
            }
            System.out.println(maxP);
        }
    }
}

この時点で残り6分程度で、Eは全く間に合わず。

0
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
0
0