Ejemplo n.º 1
0
        public void Solve()
        {
            var cin = new MyInputStream();
            var N   = cin.ReadInt();
            var M   = cin.ReadInt();
            var c   = new int[M, N];

            const int START        = -1;
            const int GOAL         = 0;
            const int IMPENETRABLE = -2;

            Point s = new Point();

            for (int y = 0; y < N; ++y)
            {
                var line = cin.Read();
                for (int x = 0; x < M; ++x)
                {
                    switch (line[x])
                    {
                    case 's':
                        s       = new Point(x, y);
                        c[x, y] = START;
                        break;

                    case 'g':
                        c[x, y] = GOAL;
                        break;

                    case '#':
                        c[x, y] = IMPENETRABLE;
                        break;

                    default:
                        c[x, y] = (int)(line[x] - '0');
                        break;
                    }
                }
            }

            var dxy = new[] { -1, 0, 1, 0, -1 };

            // ??????????brightness??????????????
            Func <double, bool> Check = (brightness) =>
            {
                // ?????????????
                var visited = new bool[M, N];

                // bfs?????
                var q = new Queue <Turn>();

                //  Turn( ?????, ??????????????, ?????)
                q.Enqueue(new Turn(time: 1, bright: 10.0, pos: s));
                while (q.Any())
                {
                    var now = q.Dequeue();

                    // ???????????????brightness?????
                    if (now.b < brightness)
                    {
                        continue;
                    }

                    // ???????
                    if (visited[now.p.X, now.p.Y])
                    {
                        continue;
                    }
                    visited[now.p.X, now.p.Y] = true;

                    // ??????4??????
                    for (int i = 0; i < 4; ++i)
                    {
                        var nx = now.p.X + dxy[i];
                        var ny = now.p.Y + dxy[i + 1];
                        // ??????????
                        if (nx < 0 || nx >= M)
                        {
                            continue;
                        }
                        if (ny < 0 || ny >= N)
                        {
                            continue;
                        }

                        // ??????????????????????(?????)
                        if (visited[nx, ny])
                        {
                            continue;
                        }

                        // ????????????
                        if (c[nx, ny] == GOAL)
                        {
                            return(true);
                        }

                        // ?????????, ???????????????????
                        if (c[nx, ny] < 0)
                        {
                            continue;
                        }

                        // ?????????????????????
                        var nb = Math.Min(Math.Pow(0.99, now.t) * c[nx, ny], now.b);
                        q.Enqueue(new Turn(now.t + 1, nb, new Point(nx, ny)));
                    }
                }
                return(false);
            };

            // ???????????????????
            if (!Check(0))
            {
                WriteLine(-1);
                return;
            }

            // ???(??)????????????????
            var l = 0d;
            var r = 10d;

            for (int i = 0; i < 50; ++i)
            {
                if (Math.Abs(r - l) < 1e-15)
                {
                    break;
                }
                var mid = (l + r) / 2d;
                if (Check(mid))
                {
                    l = mid;
                }
                else
                {
                    r = mid;
                }
            }
            WriteLine(l);
        }
Ejemplo n.º 2
0
        public void Solve()
        {
            var cin = new MyInputStream();

            N = cin.ReadInt();
            M = cin.ReadInt();
            c = new int[M, N];

            const int START        = -1;
            const int IMPENETRABLE = -2;

            Point s = new Point();

            for (int y = 0; y < N; ++y)
            {
                var line = cin.Read();
                for (int x = 0; x < M; ++x)
                {
                    switch (line[x])
                    {
                    case 's':
                        s.X     = x;
                        s.Y     = y;
                        c[x, y] = START;
                        break;

                    case 'g':
                        c[x, y] = GOAL;
                        break;

                    case '#':
                        c[x, y] = IMPENETRABLE;
                        break;

                    default:
                        c[x, y] = (int)(line[x] - '0');
                        break;
                    }
                }
            }

            // ???????????????????
            if (!Check(0, s))
            {
                WriteLine(-1);
                return;
            }

            // ???(??)????????????????
            var l = 0d;
            var r = 10d;

            for (int i = 0; i < 50; ++i)
            {
                if (Math.Abs(r - l) < 1e-15)
                {
                    break;
                }
                var mid = (l + r) / 2d;
                if (Check(mid, s))
                {
                    l = mid;
                }
                else
                {
                    r = mid;
                }
            }
            WriteLine(l);
        }