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); }
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")); }