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