書きたいことを書きたいだけ。

とある会社員の生活記録。

AtCoder Beginner Contest 148参戦記

はじめに

ABC148に参戦しました。
競プロは実はこれが初めてだったりします。
てなわけで書いたコードを忘れないためと復習がてらよくある参戦記を書いておきます。
C#で書いています。

結果

先に結果を書いておくとABCDの4完でした。
最初の30分でABCDを終わらせて残りの時間ずっとE問題を考えていました。
こういう場合、Fに飛んでもよかったかもしれませんが最初ということで・・・

A - Round One

var a = 6;
var N = int.Parse(Console.ReadLine());
var N1 = int.Parse(Console.ReadLine());
Console.WriteLine(a - N - N1);

1+2+3 = 6なので6から入力を二つ足したものを引くと答えがでるという考え。
過去問解くときだと、なるべくショートコードにこだわったりもするもんですが、本番だと取り敢えず愚直にコード書きました。

B - Strings with the Same Length

与えられた文字列を前から順番に交互に並べる。

var N = int.Parse(Console.ReadLine());
 var input_string = Console.ReadLine().Split();
 for(int i = 0; i < input_string[0].Length; i++)
 {
    Console.Write(input_string[0][i]);
    Console.Write(input_string[1][i]);
  }

最初のvar N に代入する必要はありませんが気にしないでおこう。
入力から文字を読み取って、いったんstring[] 型のinput_stringに保存。
その後、for文でinput_string[0]とinput_string[1]を前から交互に出力することで完成。

C - Snack

        public static void Main(string[] args)
        {
            var input_num = Console.ReadLine().Split().Select(long.Parse).ToArray();
            Console.WriteLine(Lcm(input_num[0], input_num[1]));
        }
        static long Gcd(long a, long b)
        {
            var v = new[] { a, b };
            while (v[1] != 0) { v = new[] { v[1], v[0] % v[1] }; }
            return v[0];
        }

        static long Lcm(long a, long b)
        {
            return a / Gcd(a, b) * b;
        }

問題文に惑わされずに最小公倍数の問題と見抜いたらあとはコードを調べるだけ。
さすがに自分で実装すると時間がもったいないので拝借させていただきました。

D - Brick Break

        public static void Main(string[] args)
        {
            var N = int.Parse(Console.ReadLine());
            var input_num = Console.ReadLine().Split().Select(int.Parse).ToArray();

            var stack = new Stack<int>();
            foreach (int num in input_num.Reverse())
            {
                stack.Push(num);
            }
            var i = 1;
            var count = 0;
            while (stack.Count > 0)
            {
                if(stack.Peek() == i) { count += 1; i += 1; };
                stack.Pop();
            }
            Console.WriteLine(count==0?-1:N-count);
        }

スタックを使って実装。
まずは与えられた数列を逆順にしてスタックに放り込みます。
その後、スタックが無くなるまで取り出していきます。
レンガの中から左からi番目のものに書かれた整数がiであることが必要であるので、var i=1の部分で欲しい数値を記録しておきます。
つまり、最初はレンガの数字が「1」が欲しいので1を記録。レンガの数字の「1」が出た後は欲しい数字は「2」になるので2を記録します。
例として、入力例の「3 1 4 1 5 9 2 6 5 3 」を考えると
この中で1,2,3・・・・と並んでいるのは左から2番目と7番目と10番目です。
つまり3個は並んでいるので並んでいないのは7個なのでそれを消せばいいわけです。
てことでN-countが答えで解答。
後から見直すとvar iとvar count の二つもいらなかったな。
入力のとこもわざわざスタックじゃなくても普通に配列のままで処理できるはずなのになぜスタックにしたかは謎。
たぶんそっちのほうが考えやすかったのかな・・・
急いでプログラム書いているときはくっそ適当なコードになりがち。

E問題以下

解けず。時間はあったのでE考えてたけど思い浮かばなかった。