結果

問題 No.5006 Hidden Maze
ユーザー どららどらら
提出日時 2022-06-12 17:35:26
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
AC  
実行時間 178 ms / 2,000 ms
コード長 4,513 bytes
コンパイル時間 4,273 ms
実行使用メモリ 22,876 KB
スコア 89,026
平均クエリ数 110.74
最終ジャッジ日時 2022-06-12 17:35:39
合計ジャッジ時間 12,104 ms
ジャッジサーバーID
(参考情報)
judge11 / judge13
純コード判定しない問題か言語
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 24 ms
21,952 KB
testcase_01 AC 44 ms
21,940 KB
testcase_02 AC 22 ms
22,576 KB
testcase_03 AC 22 ms
21,892 KB
testcase_04 AC 26 ms
22,612 KB
testcase_05 AC 32 ms
22,004 KB
testcase_06 AC 29 ms
22,016 KB
testcase_07 AC 23 ms
21,768 KB
testcase_08 AC 47 ms
21,928 KB
testcase_09 AC 72 ms
22,620 KB
testcase_10 AC 23 ms
22,564 KB
testcase_11 AC 20 ms
21,940 KB
testcase_12 AC 23 ms
22,564 KB
testcase_13 AC 21 ms
21,780 KB
testcase_14 AC 69 ms
21,952 KB
testcase_15 AC 19 ms
22,004 KB
testcase_16 AC 21 ms
21,904 KB
testcase_17 AC 35 ms
21,952 KB
testcase_18 AC 44 ms
21,648 KB
testcase_19 AC 20 ms
21,904 KB
testcase_20 AC 20 ms
21,940 KB
testcase_21 AC 24 ms
21,892 KB
testcase_22 AC 27 ms
22,276 KB
testcase_23 AC 25 ms
21,952 KB
testcase_24 AC 28 ms
21,916 KB
testcase_25 AC 22 ms
22,576 KB
testcase_26 AC 178 ms
21,992 KB
testcase_27 AC 28 ms
21,928 KB
testcase_28 AC 19 ms
21,928 KB
testcase_29 AC 164 ms
21,928 KB
testcase_30 AC 23 ms
22,600 KB
testcase_31 AC 22 ms
21,940 KB
testcase_32 AC 41 ms
21,992 KB
testcase_33 AC 25 ms
21,928 KB
testcase_34 AC 22 ms
22,644 KB
testcase_35 AC 21 ms
22,264 KB
testcase_36 AC 26 ms
21,892 KB
testcase_37 AC 99 ms
22,876 KB
testcase_38 AC 32 ms
22,600 KB
testcase_39 AC 21 ms
21,896 KB
testcase_40 AC 22 ms
21,940 KB
testcase_41 AC 23 ms
22,216 KB
testcase_42 AC 37 ms
21,892 KB
testcase_43 AC 22 ms
22,632 KB
testcase_44 AC 21 ms
21,940 KB
testcase_45 AC 39 ms
22,264 KB
testcase_46 AC 86 ms
21,904 KB
testcase_47 AC 20 ms
22,228 KB
testcase_48 AC 48 ms
21,928 KB
testcase_49 AC 96 ms
22,252 KB
testcase_50 AC 23 ms
21,940 KB
testcase_51 AC 25 ms
21,892 KB
testcase_52 AC 32 ms
21,928 KB
testcase_53 AC 28 ms
21,780 KB
testcase_54 AC 34 ms
21,756 KB
testcase_55 AC 30 ms
22,716 KB
testcase_56 AC 24 ms
21,772 KB
testcase_57 AC 40 ms
21,904 KB
testcase_58 AC 21 ms
21,792 KB
testcase_59 AC 25 ms
22,060 KB
testcase_60 AC 22 ms
21,928 KB
testcase_61 AC 19 ms
21,880 KB
testcase_62 AC 21 ms
21,892 KB
testcase_63 AC 20 ms
21,892 KB
testcase_64 AC 31 ms
22,216 KB
testcase_65 AC 24 ms
22,576 KB
testcase_66 AC 57 ms
22,600 KB
testcase_67 AC 34 ms
21,792 KB
testcase_68 AC 45 ms
21,892 KB
testcase_69 AC 42 ms
22,420 KB
testcase_70 AC 21 ms
21,792 KB
testcase_71 AC 24 ms
22,240 KB
testcase_72 AC 20 ms
21,892 KB
testcase_73 AC 28 ms
21,892 KB
testcase_74 AC 24 ms
21,792 KB
testcase_75 AC 24 ms
21,892 KB
testcase_76 AC 19 ms
21,916 KB
testcase_77 AC 47 ms
21,904 KB
testcase_78 AC 18 ms
21,820 KB
testcase_79 AC 61 ms
21,904 KB
testcase_80 AC 24 ms
22,240 KB
testcase_81 AC 28 ms
21,600 KB
testcase_82 AC 24 ms
21,892 KB
testcase_83 AC 19 ms
21,904 KB
testcase_84 AC 42 ms
22,456 KB
testcase_85 AC 33 ms
21,792 KB
testcase_86 AC 19 ms
21,880 KB
testcase_87 AC 22 ms
22,600 KB
testcase_88 AC 29 ms
21,892 KB
testcase_89 AC 154 ms
22,264 KB
testcase_90 AC 23 ms
21,940 KB
testcase_91 AC 20 ms
22,264 KB
testcase_92 AC 29 ms
21,940 KB
testcase_93 AC 19 ms
21,928 KB
testcase_94 AC 24 ms
21,952 KB
testcase_95 AC 27 ms
21,940 KB
testcase_96 AC 24 ms
21,892 KB
testcase_97 AC 31 ms
21,928 KB
testcase_98 AC 38 ms
21,992 KB
testcase_99 AC 26 ms
21,756 KB
権限があれば一括ダウンロードができます
コンパイルメッセージ
main.cpp: 関数 ‘int inv_k(int)’ 内:
main.cpp:82:1: 警告: 制御が非 void 関数の終りに到達しました [-Wreturn-type]
   82 | }
      | ^

ソースコード

diff #

#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-100);
  if(rate > 1.0) rate = 1.0;
  double start_base = 1e-9;
  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.25, 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;
}


0