結果
問題 | No.5006 Hidden Maze |
ユーザー |
![]() |
提出日時 | 2022-06-12 17:15:54 |
言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 179 ms / 2,000 ms |
コード長 | 4,476 bytes |
コンパイル時間 | 3,903 ms |
実行使用メモリ | 22,888 KB |
スコア | 88,268 |
平均クエリ数 | 118.32 |
最終ジャッジ日時 | 2022-06-12 17:16:07 |
合計ジャッジ時間 | 11,473 ms |
ジャッジサーバーID (参考情報) |
judge15 / judge14 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 100 |
コンパイルメッセージ
main.cpp: 関数 ‘int inv_k(int)’ 内: main.cpp:81:1: 警告: 制御が非 void 関数の終りに到達しました [-Wreturn-type] 81 | } | ^
ソースコード
#include <bits/stdc++.h>#include <atcoder/all>using namespace std;using namespace atcoder;#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)#define rep(i,n) REP(i,0,n)#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)#define ALLOF(c) (c).begin(), (c).end()typedef long long ll;typedef unsigned long long ull;//using mint = modint1000000007;//using mint = modint998244353;uint32_t xor128() {static uint32_t x = 123456789, y = 362436069, z = 521288629, w = 88675123;uint32_t t;t = (x ^ (x << 11));x = y;y = z;z = w;return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));}inline float frand() {return xor128() % UINT32_MAX / static_cast<float>(UINT32_MAX);}struct P {int y, x;double p;};bool operator<(const P& a, const P& b){return a.p < b.p;}int H, W;int step;const int MAX_STEP = 1000;double fail_prob;const string angle = "UDLR";int get_angle(char c){if(c == 'U') return 0;if(c == 'D') return 1;if(c == 'L') return 2;if(c == 'R') return 3;assert(false);}int vy[4] = {-1,1,0,0};int vx[4] = {0,0,-1,1};double get_noise(){double rate = step / (double)MAX_STEP;double start_base = 1e-7;double end_base = 0.998;double base = start_base + (end_base - start_base) * rate;return base * frand();}struct Wall {int pass;int stop;Wall():pass(0),stop(0){}double get_prob(){if(pass > 0) return 1.0 - get_noise();else return max(1e-100, 0.9 * pow(0.5, stop) - get_noise());}void count_pass(){ pass++; }void count_stop(){ stop++; }};Wall wall_right[25][25];Wall wall_down[25][25];int inv_k(int k){assert(0<=k && k<=3);if(k == 0) return 1;if(k == 1) return 0;if(k == 2) return 3;if(k == 3) return 2;}// 移動可能確率double get_prob(int y, int x, int k){int ny = y + vy[k];int nx = x + vx[k];if(ny<0 || H<=ny || nx<0 || W<=nx) return 1e-100;if(k == 0) return wall_down[ny][nx].get_prob();if(k == 1) return wall_down[y][x].get_prob();if(k == 2) return wall_right[ny][nx].get_prob();if(k == 3) return wall_right[y][x].get_prob();assert(false);}void update_pass(int y, int x, int k){int ny = y + vy[k];int nx = x + vx[k];if(ny<0 || H<=ny || nx<0 || W<=nx) return;if(k == 0) wall_down[ny][nx].count_pass();if(k == 1) wall_down[y][x].count_pass();if(k == 2) wall_right[ny][nx].count_pass();if(k == 3) wall_right[y][x].count_pass();}void update_stop(int y, int x, int k){int ny = y + vy[k];int nx = x + vx[k];if(ny<0 || H<=ny || nx<0 || W<=nx) return;if(k == 0) wall_down[ny][nx].count_stop();if(k == 1) wall_down[y][x].count_stop();if(k == 2) wall_right[ny][nx].count_stop();if(k == 3) wall_right[y][x].count_stop();}double calc_fail_p(int c){double ret = 0;rep(i,c){ret += log(1.0 - fail_prob);}ret += log(fail_prob);return exp(ret);}void dump(){rep(i,H){rep(j,W){cout << "(" << wall_down[i][j].get_prob() << "," << wall_right[i][j].get_prob() << ") ";}cout << endl;}}string get_answer(){vector<vector<double>> dp(H, vector<double>(W, -1e100));vector<vector<int>> prev(H, vector<int>(W, -1));priority_queue<P> que;que.push((P){0,0,0.0});dp[0][0] = 0.0;while(!que.empty()){P p = que.top(); que.pop();if(dp[p.y][p.x] > p.p) continue;rep(k,4){int ny = p.y + vy[k];int nx = p.x + vx[k];if(ny<0 || H<=ny || nx<0 || W<=nx) continue;double logprob = log(get_prob(p.y,p.x,k));if(dp[ny][nx] < dp[p.y][p.x] + logprob){dp[ny][nx] = dp[p.y][p.x] + logprob;prev[ny][nx] = inv_k(k);que.push((P){ny,nx,dp[ny][nx]});}}}int y = H-1, x = W-1;string ret;while(!(y == 0 && x == 0)){int k = prev[y][x];ret += angle[inv_k(k)];y = y + vy[k];x = x + vx[k];}reverse(ALLOF(ret));return ret;};void update(const string& ans, int fail){int y = 0, x = 0;rep(i,fail){int k = get_angle(ans[i]);update_pass(y, x, k);y = y + vy[k];x = x + vx[k];}int k = get_angle(ans[fail]);update_stop(y, x, k);}int main(){double fp;cin >> H >> W >> fp;fail_prob = fp / 100.0;step = 0;while(true){string ans = get_answer();cout << ans << endl;int ret;cin >> ret;//cerr << step << "\t" << ret << "\t" << ans << endl;if(ret == -1) break;update(ans, ret);step++;}return 0;}