예제 #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        = 0;
            const int GOAL         = -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       = 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 };
            Func <double, bool> Check = (brightness) =>
            {
                var visited = new bool[M, N];
                var q       = new Queue <Turn>();
                q.Enqueue(new Turn(time: 1, bright: 10.0, pos: s));
                while (q.Any())
                {
                    var now = q.Dequeue();
                    if (now.b < brightness)
                    {
                        continue;
                    }
                    if (visited[now.p.X, now.p.Y])
                    {
                        continue;
                    }
                    visited[now.p.X, now.p.Y] = true;
                    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);
        }
예제 #2
0
        public void Solve()
        {
            var cin = new MyInputStream();
            var N   = cin.ReadInt();
            var M   = cin.ReadInt();
            var c   = new int[N, M];

            const int START   = -1;
            const int GOAL    = -2;
            const int INVALID = -3;

            var sx = 0;
            var sy = 0;

            for (int i = 0; i < N; ++i)
            {
                var l = cin.Read();
                for (int j = 0; j < M; ++j)
                {
                    if (l[j] == 's')
                    {
                        sx      = j;
                        sy      = i;
                        c[i, j] = START;
                    }
                    else if (l[j] == 'g')
                    {
                        c[i, j] = GOAL;
                    }
                    else if (l[j] == '#')
                    {
                        c[i, j] = INVALID;
                    }
                    else
                    {
                        c[i, j] = l[j] - '0';
                    }
                }
            }

            var table = new double[10, N *M + 1];

            for (int i = 0; i <= N * M; ++i)
            {
                var brightness = Math.Pow(0.99, i);
                for (int j = 1; j < 10; ++j)
                {
                    table[j, i] = brightness * j;
                }
            }

            var dxy = new int[] { 0, 1, 0, -1, 0 };
            Func <double, bool> bfs = (bright) => {
                var visited = new bool[M, N];
                var pos     = new Pair <Pair <int, int>, Pair <int, double> >(new Pair <int, int>(sx, sy), new Pair <int, double>(0, 10));
                var q       = new Queue <Pair <Pair <int, int>, Pair <int, double> > >();
                q.Enqueue(pos);

                while (q.Any())
                {
                    var now = q.Dequeue();
                    var x   = now.First.First;
                    var y   = now.First.Second;
                    var t   = now.Second.First;
                    var m   = now.Second.Second;

                    if (m < bright)
                    {
                        continue;
                    }

                    if (visited[x, y])
                    {
                        continue;
                    }
                    else
                    {
                        visited[x, y] = true;
                    }

                    if (c[y, x] == GOAL)
                    {
                        return(true);
                    }
                    if (c[y, x] == INVALID)
                    {
                        continue;
                    }

                    for (int i = 0; i < 4; ++i)
                    {
                        int nx = x + dxy[i];
                        int ny = y + dxy[i + 1];
                        if (nx < 0 || nx >= M)
                        {
                            continue;
                        }
                        if (ny < 0 || ny >= N)
                        {
                            continue;
                        }

                        double min  = (c[y, x] == START) ? 10 : Math.Min(m, table[c[y, x], t]);
                        var    next = new Pair <Pair <int, int>, Pair <int, double> >(new Pair <int, int>(nx, ny), new Pair <int, double>(t + 1, min));
                        q.Enqueue(next);
                    }
                }
                return(false);
            };

            if (!bfs(0))
            {
                WriteLine("-1");
                return;
            }

            double a = 0;
            double b = 10;

            while (Math.Abs(a - b) > 1e-10)
            //for (int i = 0; i < 50; ++i)
            {
                double mid = (a + b) / 2.0;
                if (bfs(mid))
                {
                    a = mid;
                }
                else
                {
                    b = mid;
                }
            }
            Console.WriteLine(a.ToString("F10"));
        }