東大卒のお金やりくり奮闘記~株、家計、趣味、経済~

東大卒でメーカー勤務の私がセミリタイアするために投資などを頑張っていこうという趣旨で始めたブログです。既婚男性です。株、家計、趣味、経済の話をメインにゆるゆる話します。

ABC184で書いたコード

using System;
using System.Numerics;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Collections;

namespace debug
{
    class main
    {
        static void Main(string args)
        {
            //問題クラスを展開
            ProgramD a = new ProgramD();
            a.main();//実行する

        }

    }
    //ABC184
    class ProgramA
    {
        public void main()
        {
            //入力
            string s1 = Console.ReadLine().Split();
            int a = int.Parse(s1[0]);
            int b = int.Parse(s1[1]);
            string s2 = Console.ReadLine().Split();
            int c = int.Parse(s2[0]);
            int d = int.Parse(s2[1]);
            //a*d - b*cが答え
            Console.WriteLine(a * d - b * c);

        }
    }

    class ProgramB
    {
        public void main()
        {
            //入力
            string s1 = Console.ReadLine().Split();
            int n = int.Parse(s1[0]);
            int x = int.Parse(s1[1]);

            string s = Console.ReadLine();

            //もしxなら減点、oなら加点。
            for (int i = 0i < ni++)
            {
                if (s[i] == 'x')
                {
                    //ただしxが1点以上なら引く
                    if (x > 0)
                        x--;
                }
                else
                    x++;

            }

            //答
            Console.WriteLine(x);



        }
    }

    class ProgramC
    {
        public void main()
        {

            //入力
            string s1 = Console.ReadLine().Split();
            long a = long.Parse(s1[0]);
            long b = long.Parse(s1[1]);
            string s2 = Console.ReadLine().Split();
            long c = long.Parse(s2[0]);
            long d = long.Parse(s2[1]);

            //同じなら0手
            if (a == c && b == d)
            {
                Console.WriteLine(0);
                return;
            }

            //1手の条件を満たすなら1手
            if (a - b == c - d || a + b == c + d || (Math.Abs(a - c) + Math.Abs(b - d) <= 3))
            {
                Console.WriteLine(1);
                return;
            }

            //ななめグリットなら必ず2手になる。この条件はこれ
            if *1;

        }


        //繰り返し求める
        static double f(int a,int b,int c)
        {
            //0以外のときはすでに求まっているので出す
            if (dp[abc] != 0)
                return dp[abc];

            //100のときは0である
            if (a == 100 || b == 100 || c == 100)
                return 0;

            double ans = 0;
            //それぞれの期待値を出す
            ans += (f(a + 1bc) + 1) * a / (a + b + c);
            ans += (f(ab + 1c) + 1) * b / (a + b + c);
            ans += (f(abc + 1) + 1) * c / (a + b + c);
            dp[abc] = ans;//確率があればdp残す

            //答えを返す
            return ans;

        }

    }

    class ProgramE
    {
        public void main()
        {
            //入力
            string a = Console.ReadLine().Split(' ');
            long r = long.Parse(a[0]);
            long c = long.Parse(a[1]);
            long sx = 0;
            long sy = 0;
            long gx = 0;
            long gy = 0;

            long[,] found = new long[rc];//探索したかどうかを見る
            char[,] maze = new char[rc];
            List<Task> task = new List<Task>[26];
            for (int i = 0i < 26i++)
                task[i] = new List<Task>();
            int[] flag = new int[26];

            //迷路作成
            for (long i = 0i < ri++)
            {
                string d = Console.ReadLine();
                for (int j = 0j < cj++)
                {
                    //#と.は普通にいれる
                    if(d[j] == '#' || d[j] == '.')
                        maze[ij] = d[j];
                    else if(d[j] == 'S')
                    {
                        maze[ij] = d[j];
                        sx = i;
                        sy = j;
                    }
                    else if (d[j] == 'G')
                    {
                        maze[ij] = d[j];
                        gx = i;
                        gy = j;
                    }
                    else
                    {//ワープ位置は記録
                        maze[ij] = d[j];
                        task[d[j] - 'a'].Add(new Task(ij));
                    }

                }
                

            }

            

            //キューを用意
            Queue<longqx = new Queue<long>();
            Queue<longqy = new Queue<long>();

            //スタートを入れる
            qx.Enqueue(sx);
            qy.Enqueue(sy);
            found[sxsy] = -1;

            long rank = 0;

            while (rank != 2000*2000)
            {
                long num = qx.Count;
                //キューがなくなったらたどり着けないってこと
                if(num == 0)
                {
                    Console.WriteLine(-1);
                    return;
                }
                for (long i = 0i < numi++)
                {
                    //取り出し
                    long tx = qx.Dequeue();
                    long ty = qy.Dequeue();

                    //ゴールなら出力
                    if (tx == gx && ty == gy)
                    {
                        Console.WriteLine(rank);
                        return;
                    }

                    //#ならいけないので更新しない
                    if (maze[txty] == '#')
                        continue;

                    //ワープ位置のときはワープ処理する
                    if (maze[txty] != '.' && maze[txty] != '#' && maze[txty] != 'S')
                    {
                        if (flag[maze[txty] - 'a'] != 1)
                        {
                            for (int j = 0j < task[maze[txty] - 'a'].Countj++)
                            {
                                //同じ位置は飛ばす
                                if (task[maze[txty] - 'a'][j].x == tx && task[maze[txty] - 'a'][j].y == ty)
                                    continue;

                                //それ以外はきゅーにいれる
                                if (found[task[maze[txty] - 'a'][j].xtask[maze[txty] - 'a'][j].y] == 0)
                                {
                                    qx.Enqueue(task[maze[txty] - 'a'][j].x);
                                    qy.Enqueue(task[maze[txty] - 'a'][j].y);
                                    found[task[maze[txty] - 'a'][j].xtask[maze[txty] - 'a'][j].y] = -1;
                                }

                            }
                        }

                        //一回そのワープをしたらそれ以降は使わないのでこの処理を入れる
                        flag[maze[txty] - 'a'] = 1;
                    }


                    //ワープ位置以外4方向見る
                    for (long j = 0j < 4j++)
                    {
                        if (j == 0)
                            tx--;
                        else if (j == 1)
                            tx += 2;
                        else if (j == 2)
                        {
                            tx--;
                            ty--;
                        }
                        else
                            ty += 2;

                        //範囲内かつ未検索
                        if (0 <= tx && tx < r && 0 <= ty && ty < c)
                            if (found[txty] == 0)
                            {
                                qx.Enqueue(tx);
                                qy.Enqueue(ty);
                                found[txty] = -1;
                            }
                    }
                }

                //ランクを足す
                rank++;
            }

        }
    }

    //ワープ位置を記録するもの
    public class Task
    {
        public long x;
        public long y;
        public Task(long xlong y)
        {
            this.x = x;
            this.y = y;
        }
    }

}





*1:a + b) % 2 == (c + d) % 2)

            {
                Console.WriteLine(2);
                return;
            }

            if ((a - b) % 2 == (c - d) % 2)
            {
                Console.WriteLine(2);
                return;
            }


            //また、周辺3マス以内の移動で、一方向斜めで動けるなら2手
            for (long i = a - 3i <= a + 3i++)
                for (long j = b - 3j <= b + 3j++)
                {
                    if (Math.Abs(a - i) + Math.Abs(b - j) > 3)
                        continue;

                    if (a == i && b == j)
                        continue;

                    if (i - j == c - d || i + j == c + d)
                    {
                        Console.WriteLine(2);
                        return;
                    }

                }

            //それ以外は3手でどうにかなる
            Console.WriteLine(3);

        }



    }


    class ProgramD
    {
        //メモ化しておく
        static double[,,] dp = new double[101101101];

        public void main()
        {
            //入力
            string[] s = Console.ReadLine().Split();
            int a = int.Parse(s[0]);
            int b = int.Parse(s[1]);
            int c = int.Parse(s[2]);

            //期待値を出す
            Console.WriteLine(f(a,b,c