提出 #47959710


ソースコード 拡げる

// DFSのサンプルコード

// VSCODEの拡張機能C/C++の設定
// "C_Cpp.clang_format_sortIncludes": true,
// "C_Cpp.clang_format_style": "Google" でフォーマット済み

#include <algorithm>  //shuffleに必要
#include <array>
#include <chrono>    // 時間計測
#include <iostream>  //入出力
#include <random>
#include <vector>

using namespace std;  // 自己責任で使おう

// 乱数を生成するクラス
class Random {
 public:
  std::mt19937 mt_;  // シード0でメルセンヌツイスターの乱数生成器を初期化
  // 0以上1.0未満の実数の範囲の乱数生成
  uniform_real_distribution<double> dd_{0, 1.0};

  // seedを指定して初期化
  Random(const int seed = 0) : mt_(std::mt19937(seed)) {}

  // 0以上m未満の整数の範囲の乱数
  inline int nextInt(const int m) {
    uniform_int_distribution<int> di(0, m - 1);
    return di(mt_);
  }

  // 0以上1.0未満の実数の範囲の乱数
  inline double nextDouble() { return dd_(mt_); }

  // 0以上1.0未満の実数の範囲の乱数のlog。焼きなまし法で使いやすい。
  inline double nextLog() { return log(dd_(mt_)); }
};

Random rnd{};

constexpr int H = 50;         // 盤面の縦方向の大きさ
constexpr int W = 50;         // 盤面の横方向の大きさ
constexpr int TILE_N = 2500;  // タイルの総数。2500枚よりは絶対少ない
int first_coord;  // 高橋くんの初期位置:(y,x)はy*W+xとして表現する
int tiles[H * W];  // tiles[coord1]とtiles[coord2]が同じなら同じタイル
int points[H * W];  // tiles[coord]を訪れた場合の得点
vector<vector<int>> next_coords{H * W};  // next_coords[coord]=coordの隣のリスト

// 始点を指定して探索するクラス
class DfsSolver {
 public:
  // visiteds_[tile]はtileが踏まれたかどうかを表す
  array<bool, TILE_N> visiteds_;
  vector<int> path_;       // coordのリスト。今探索中のパス
  vector<int> best_path_;  // coordのリスト。今のところ一番いいパス
  int best_score_ = 0;     // 今のところ一番いいスコア
  int score_ = 0;          // 今探索中のパスのスコア
  int remaining_search_cnt_;  // 残り探索回数

  // dfsを開始する。dfsは再帰で実装するので開始する関数が必要
  void start() {
    best_path_.clear();
    score_ = 0;
    visiteds_.fill(0);
    path_.clear();
    remaining_search_cnt_ = 4000;
    dfs(first_coord);
  }

 private:
  // coordを始点とした探索
  void dfs(const int coord) {
    path_.emplace_back(coord);
    score_ += points[coord];
    visiteds_[tiles[coord]] = 1;

    if (best_score_ < score_) {
      best_score_ = score_;
      best_path_ = path_;
    }
    remaining_search_cnt_--;
    if (remaining_search_cnt_ == 0) return;
    vector<int> legal_next_coords;
    for (const auto &next_coord : next_coords[coord]) {
      if (!visiteds_[tiles[next_coord]]) {
        legal_next_coords.emplace_back(next_coord);
      }
    }
    for (const auto &next_coord : legal_next_coords) {
      if (!visiteds_[tiles[next_coord]]) {
        dfs(next_coord);
        if (remaining_search_cnt_ == 0) return;
      }
    }
    path_.pop_back();
    score_ -= points[coord];
    visiteds_[tiles[coord]] = 0;
  }
};

struct State {
  vector<int> now_path_;  // coordのリスト。今までに遷移してきた現在のパス

  // 初期解を生成する
  void solve_first() {
    DfsSolver dfs_solver{};
    dfs_solver.start();
    this->now_path_ = dfs_solver.path_;
  }

  // 入力を受け取る
  void input() {
    int sy, sx;
    cin >> sy >> sx;
    first_coord = sy * W + sx;
    for (int y = 0; y < H; y++) {
      for (int x = 0; x < W; x++) {
        cin >> tiles[y * W + x];
      }
    }
    for (int y = 0; y < H; y++) {
      for (int x = 0; x < W; x++) {
        cin >> points[y * W + x];
      }
    }
  }

  // 解を出力する
  void output() {
    // now_pathは座標のリストになっているため、移動方向に直して出力する
    string res;
    for (int i = 0; i < now_path_.size() - 1; i++) {
      int diff = now_path_[i + 1] - now_path_[i];
      if (diff == 1) {
        res.push_back('R');
      } else if (diff == -1) {
        res.push_back('L');
      } else if (diff == W) {
        res.push_back('D');
      } else if (diff == -W) {
        res.push_back('U');
      }
    }
    cout << res << endl;
  }
};

void initialize_global_info() {
  // 各座標から行ける場所(盤面の枠内かつタイルが異なる)をメモしておく
  const int dy[4] = {1, 0, -1, 0};
  const int dx[4] = {0, 1, 0, -1};
  for (int y = 0; y < H; y++) {
    for (int x = 0; x < W; x++) {
      int coord = y * W + x;
      for (int d = 0; d < 4; d++) {
        int ty = y + dy[d];
        int tx = x + dx[d];
        if (ty >= 0 && ty < H && tx >= 0 && tx < W) {
          int tcoord = ty * W + tx;
          if (tiles[coord] != tiles[tcoord]) {
            next_coords[coord].emplace_back(tcoord);
          }
        }
      }
    }
  }
}

int main() {
  State state;
  // 入力を受け取る
  state.input();
  // 前計算などの準備
  initialize_global_info();
  // DFSで解を求める
  state.solve_first();
  // 解を出力する
  state.output();
  return 0;
}

提出情報

提出日時
問題 A - Walking on Tiles
ユーザ thunder
言語 C++ 20 (gcc 12.2)
得点 2907007
コード長 5462 Byte
結果 AC
実行時間 3 ms
メモリ 4036 KiB

コンパイルエラー

Main.cpp: In member function ‘void State::output()’:
Main.cpp:132:23: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<int>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
  132 |     for (int i = 0; i < now_path_.size() - 1; i++) {
      |                     ~~^~~~~~~~~~~~~~~~~~~~~~

ジャッジ結果

セット名 test_ALL
得点 / 配点 2907007 / 25000000
結果
AC × 100
セット名 テストケース
test_ALL test_0000.txt, test_0001.txt, test_0002.txt, test_0003.txt, test_0004.txt, test_0005.txt, test_0006.txt, test_0007.txt, test_0008.txt, test_0009.txt, test_0010.txt, test_0011.txt, test_0012.txt, test_0013.txt, test_0014.txt, test_0015.txt, test_0016.txt, test_0017.txt, test_0018.txt, test_0019.txt, test_0020.txt, test_0021.txt, test_0022.txt, test_0023.txt, test_0024.txt, test_0025.txt, test_0026.txt, test_0027.txt, test_0028.txt, test_0029.txt, test_0030.txt, test_0031.txt, test_0032.txt, test_0033.txt, test_0034.txt, test_0035.txt, test_0036.txt, test_0037.txt, test_0038.txt, test_0039.txt, test_0040.txt, test_0041.txt, test_0042.txt, test_0043.txt, test_0044.txt, test_0045.txt, test_0046.txt, test_0047.txt, test_0048.txt, test_0049.txt, test_0050.txt, test_0051.txt, test_0052.txt, test_0053.txt, test_0054.txt, test_0055.txt, test_0056.txt, test_0057.txt, test_0058.txt, test_0059.txt, test_0060.txt, test_0061.txt, test_0062.txt, test_0063.txt, test_0064.txt, test_0065.txt, test_0066.txt, test_0067.txt, test_0068.txt, test_0069.txt, test_0070.txt, test_0071.txt, test_0072.txt, test_0073.txt, test_0074.txt, test_0075.txt, test_0076.txt, test_0077.txt, test_0078.txt, test_0079.txt, test_0080.txt, test_0081.txt, test_0082.txt, test_0083.txt, test_0084.txt, test_0085.txt, test_0086.txt, test_0087.txt, test_0088.txt, test_0089.txt, test_0090.txt, test_0091.txt, test_0092.txt, test_0093.txt, test_0094.txt, test_0095.txt, test_0096.txt, test_0097.txt, test_0098.txt, test_0099.txt
ケース名 結果 実行時間 メモリ
test_0000.txt AC 2 ms 3872 KiB
test_0001.txt AC 2 ms 3656 KiB
test_0002.txt AC 2 ms 3692 KiB
test_0003.txt AC 2 ms 3776 KiB
test_0004.txt AC 2 ms 3824 KiB
test_0005.txt AC 2 ms 4000 KiB
test_0006.txt AC 2 ms 3840 KiB
test_0007.txt AC 2 ms 3848 KiB
test_0008.txt AC 2 ms 4012 KiB
test_0009.txt AC 2 ms 3904 KiB
test_0010.txt AC 2 ms 3832 KiB
test_0011.txt AC 2 ms 3832 KiB
test_0012.txt AC 2 ms 3880 KiB
test_0013.txt AC 2 ms 3848 KiB
test_0014.txt AC 2 ms 3848 KiB
test_0015.txt AC 2 ms 3980 KiB
test_0016.txt AC 2 ms 3812 KiB
test_0017.txt AC 2 ms 3828 KiB
test_0018.txt AC 2 ms 3720 KiB
test_0019.txt AC 2 ms 3956 KiB
test_0020.txt AC 2 ms 3932 KiB
test_0021.txt AC 2 ms 3828 KiB
test_0022.txt AC 2 ms 3860 KiB
test_0023.txt AC 2 ms 3812 KiB
test_0024.txt AC 2 ms 3832 KiB
test_0025.txt AC 2 ms 3844 KiB
test_0026.txt AC 2 ms 3852 KiB
test_0027.txt AC 2 ms 3836 KiB
test_0028.txt AC 2 ms 3836 KiB
test_0029.txt AC 2 ms 3812 KiB
test_0030.txt AC 2 ms 3860 KiB
test_0031.txt AC 2 ms 4036 KiB
test_0032.txt AC 2 ms 3828 KiB
test_0033.txt AC 2 ms 3752 KiB
test_0034.txt AC 2 ms 3948 KiB
test_0035.txt AC 2 ms 3824 KiB
test_0036.txt AC 2 ms 3772 KiB
test_0037.txt AC 2 ms 3928 KiB
test_0038.txt AC 2 ms 3860 KiB
test_0039.txt AC 2 ms 3792 KiB
test_0040.txt AC 2 ms 3812 KiB
test_0041.txt AC 3 ms 3844 KiB
test_0042.txt AC 2 ms 3772 KiB
test_0043.txt AC 2 ms 3976 KiB
test_0044.txt AC 2 ms 3856 KiB
test_0045.txt AC 2 ms 3804 KiB
test_0046.txt AC 2 ms 3984 KiB
test_0047.txt AC 2 ms 3816 KiB
test_0048.txt AC 2 ms 3820 KiB
test_0049.txt AC 2 ms 4020 KiB
test_0050.txt AC 2 ms 3844 KiB
test_0051.txt AC 2 ms 3832 KiB
test_0052.txt AC 2 ms 3836 KiB
test_0053.txt AC 2 ms 3768 KiB
test_0054.txt AC 2 ms 3884 KiB
test_0055.txt AC 2 ms 3944 KiB
test_0056.txt AC 2 ms 3664 KiB
test_0057.txt AC 2 ms 3660 KiB
test_0058.txt AC 2 ms 3928 KiB
test_0059.txt AC 2 ms 3632 KiB
test_0060.txt AC 2 ms 3720 KiB
test_0061.txt AC 2 ms 3788 KiB
test_0062.txt AC 2 ms 3808 KiB
test_0063.txt AC 2 ms 3860 KiB
test_0064.txt AC 2 ms 3660 KiB
test_0065.txt AC 2 ms 3860 KiB
test_0066.txt AC 2 ms 3880 KiB
test_0067.txt AC 2 ms 4008 KiB
test_0068.txt AC 2 ms 3824 KiB
test_0069.txt AC 3 ms 3920 KiB
test_0070.txt AC 2 ms 3968 KiB
test_0071.txt AC 2 ms 3704 KiB
test_0072.txt AC 2 ms 3680 KiB
test_0073.txt AC 2 ms 3860 KiB
test_0074.txt AC 2 ms 3824 KiB
test_0075.txt AC 2 ms 3740 KiB
test_0076.txt AC 2 ms 3824 KiB
test_0077.txt AC 2 ms 4028 KiB
test_0078.txt AC 2 ms 3768 KiB
test_0079.txt AC 2 ms 3768 KiB
test_0080.txt AC 2 ms 3864 KiB
test_0081.txt AC 2 ms 3792 KiB
test_0082.txt AC 2 ms 3748 KiB
test_0083.txt AC 2 ms 3836 KiB
test_0084.txt AC 2 ms 3856 KiB
test_0085.txt AC 2 ms 3916 KiB
test_0086.txt AC 2 ms 3736 KiB
test_0087.txt AC 2 ms 3800 KiB
test_0088.txt AC 2 ms 3748 KiB
test_0089.txt AC 2 ms 3872 KiB
test_0090.txt AC 2 ms 3884 KiB
test_0091.txt AC 2 ms 3776 KiB
test_0092.txt AC 2 ms 3908 KiB
test_0093.txt AC 2 ms 3900 KiB
test_0094.txt AC 2 ms 3888 KiB
test_0095.txt AC 2 ms 3836 KiB
test_0096.txt AC 2 ms 3892 KiB
test_0097.txt AC 2 ms 3732 KiB
test_0098.txt AC 2 ms 3640 KiB
test_0099.txt AC 2 ms 3872 KiB