C#でAtCoder Beginner Contest 124に参加

最近、競技プログラミングを始めました。
すごく面白い。
まだ4回くらいしか参加してないけど、勉強になるし、パズルっぽくてすごくイイ。
今回から回答だけでもコピペして、余力があれば思考の過程とかも書いていきたい。
問題はAtCoderのサイトで確認してください。
https://atcoder.jp/contests/abc124/tasks

回答は、Solveメソッドに書いている。
競技プログラムを始めるときに、C#での競技プログラム情報を集めていたときに見つけたコードで、ここに内容の詳細が書いてます。
https://qiita.com/NotFounds/items/7b166af69a6f52a332de
C#で競技プログラミングを始めたければ、上記記事を一読することをお勧めします。そして、何問か実際に過去問を解いてみると、雰囲気がわかると思います。

私も同じように、Solveメソッドの中身だけ記載しようかな。
作者の方、便利に使わせてもらってます。ありがとうございます。

さて、私の回答をコピペする前に、もう一点注意。
コードは別に正直全然きれいじゃないし、とにかく正答することを優先にゴリゴリ書いてるだけという感じです。だから、コードの綺麗さは全然保証できません。
あと、当然ですがスピードも私のコード全然はやくないです。
解法がまだ思い浮かんでない状態で書き始めたりもしてるので、無駄なところもあると思います。
そういう諸々の問題がありますよというだけの話です。

A – Buttons

        public void Solve(ConsoleInput cin)
        {
            var input = cin.ReadLine.Split(' ');
            var x = int.Parse(input[0]);
            var y = int.Parse(input[1]);

            int result = 0;
            for (int i = 0; i < 2; i++)
            {
                if (x > y)
                {
                    result += x;
                    x--;
                }
                else
                {
                    result += y;
                    y--;
                }
            }
            Console.Write(result);
        }
    }

B – Great Ocean View

        public void Solve(ConsoleInput cin)
        {
            var N = cin.ReadInt;
            var mountain = cin.ReadIntArray(N);

            int result = 0;
            for (int i = 0; i < N; i++)
            {
                bool canSee = true;
                for (int j = 0;  j < i; j++)
                {
                    if (mountain[i] - mountain[j] < 0)
                    {
                        canSee = false;
                    }
                }
                if (canSee)
                {
                    result++;
                }
            }

            Console.Write(result);
        }
    }

今後に繋げるため、反省点を挙げると、メモ化してなかったこと。
二回目のループでわざわざ全部比較する必要はなくて、最大値を保持しておいて、そこだけ比較すればよかった。

C – Coloring Colorfully

ACだったコード

        public void Solve(ConsoleInput cin)
        {
            var N = cin.ReadLine;
            var charArray = N.ToCharArray();
            var charArray2 = N.ToCharArray();
            long counter = charArray.Count();
            long result1 = 0;
            long result2 = 0;
            if (charArray2[0] == '0')
            {
                charArray2[0] = '1';
                ++result2;
            }
            else
            {
                charArray2[0] = '0';
                ++result2;
            }

            for (int i = 0; i < counter-1; i++)
            {
                if (charArray[i] == charArray[i+1])
                {
                    if (charArray[i+1] == '0')
                    {
                        charArray[i + 1] = '1';
                    }
                    else
                    {
                        charArray[i + 1] = '0';
                    }
                    ++result1;
                }

                if (charArray2[i] == charArray2[i + 1])
                {
                    if (charArray2[i + 1] == '0')
                    {
                        charArray2[i + 1] = '1';
                    }
                    else
                    {
                        charArray2[i + 1] = '0';
                    }
                    ++result2;
                }
            }
            if (result1 > result2)
            {
                Console.Write(result2.ToString());
            }
            else
            {
                Console.Write(result1.ToString());
            }
        }
    }

一度不正解出してるし、あれだわな。
C問題を一発でAC出せるように精進しよう。

不正解だったコード

        public void Solve(ConsoleInput cin)
        {
            var N = cin.ReadLine;
            var counter = N.Count();
            var charArray = N.ToCharArray();
            var charArray2 = N.ToCharArray();
            long result1 = 0;
            long result2 = 0;
            if (charArray2[0] == '0')
            {
                charArray2[0] = '1';
            }
            else
            {
                charArray2[0] = '0';
            }

            for (int i = 0; i < counter-1; i++)
            {
                if (charArray[i] == charArray[i+1])
                {
                    if (charArray[i+1] == '0')
                    {
                        charArray[i + 1] = '1';
                    }
                    else
                    {
                        charArray[i + 1] = '0';
                    } 
                    result1++;
                }

                if (charArray2[i] == charArray2[i + 1])
                {
                    if (charArray2[i + 1] == '0')
                    {
                        charArray2[i + 1] = '1';
                    }
                    else
                    {
                        charArray2[i + 1] = '0';
                    }
                    result2++;
                }
            }
            if (result1 > result2)
            {
                Console.Write(result2.ToString());
            }
            else
            {
                Console.Write(result1.ToString());
            }
        }
    }

D – Handstand

これは正解できなかったし、Youtubeで解説みたけどイマイチわからなかった。
だから結局実装できてない。。。
ちょっと今の段階では厳しいので、一度問題を寝かせます。

振り返り

っという感じで、D問題は今のところコンテスト中に解けそうにない。
今回のD問題は正答している人数も多いのに、全然解ける気配がなかった。
暫くこの問題を熟成させて、来月くらいにもう一度チャレンジしよう。
今解説動画みてわからないけど、恐らく他にもチャレンジして経験を積んでいけば理解できるはず。
こういう体験、確か中国に留学していた頃にした。そのときは、数学の問題がどうしてもわからなくて途方にくれていて、何日かしてもう一度みてもたら理解できた、というような体験でした。そのときの爽快感というか、嬉しさというか、そういうのをまた味わいたいと思ってたけど、これはもしかしたら、近いものをまた味わえるかもそれない。


今後の目標

今の目標は緑色です。今年で緑色に成りたい。
まだA,B問題がある程度解けて、なんとかC問題も解けるかもくらいだけど。
今年中にD問題も5割くらい正答できるようになりたい。
あと、アルゴリズムもちゃんと勉強する。
ソートアルゴリズムとかではなく、競プロで使えるアルゴリズムに絞って勉強する。

C#, 競プロ

Posted by takumioda