提出 #67393389
ソースコード 拡げる
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
// 1-Step Simulator: 管理用クラス
class StepSimulator {
public:
int N;
int dr[4] = {-1,1,0,0};
int dc[4] = {0,0,-1,1};
StepSimulator(int N_) : N(N_) {}
struct State {
vector<vector<double>> prob; // 現在の期待値分布
vector<vector<bool>> occ; // 岩配置マップ
};
struct Result {
vector<vector<double>> next_prob;
vector<vector<bool>> next_occ;
};
// 1ステップ実行
// 入力: current State + place (配置位置)
// 出力: 更新後の分布とマップ
Result step(const State &s, pair<int,int> place) {
auto &prob = s.prob;
auto &occ = s.occ;
vector<vector<double>> next_prob(N, vector<double>(N, 0.0));
vector<vector<bool>> next_occ = occ;
// 分配: 各セルから4方向に等確率でスライド
for(int i = 0; i < N; ++i) {
for(int j = 0; j < N; ++j) {
if (occ[i][j]) continue;
double p = prob[i][j];
if (p <= 0.0) continue;
// 各方向に確率 p/4 ずつ分配
for(int d = 0; d < 4; ++d) {
int ni = i, nj = j;
// 岩に当たるまでスライド
while (true) {
int ti = ni + dr[d], tj = nj + dc[d];
if (ti < 0 || ti >= N || tj < 0 || tj >= N || occ[ti][tj]) break;
ni = ti; nj = tj;
}
next_prob[ni][nj] += p * 0.25;
}
}
}
// 配置位置を岩に
int bi = place.first;
int bj = place.second;
next_occ[bi][bj] = true;
// そのセルの確率消去
next_prob[bi][bj] = 0.0;
return {next_prob, next_occ};
}
};
// AHC050: Monte Carlo + expectation scoring
struct Cell { int r,c; };
int N = 40, M;
vector<string> grid;
vector<Cell> empties;
int T;
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
// compute_expected_sum: Pに従ってStepSimulatorで1ステップずつ更新し、ステップごとの総期待値を加算
double compute_expected_sum(const vector<int>& P) {
// 初期State
vector<vector<double>> prob(N, vector<double>(N, 0.0));
vector<vector<bool>> occ(N, vector<bool>(N, false));
double init_p = 1.0 / T;
for (auto &c : empties) prob[c.r][c.c] = init_p;
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
if (grid[i][j] == '#') occ[i][j] = true;
StepSimulator sim(N);
StepSimulator::State state{prob, occ};
double E_sum = 0.0;
// 各ステップ
for (int idx : P) {
// 1-step
auto res = sim.step(state, {empties[idx].r, empties[idx].c});
// スコア加算: next_probの全空きセル期待値
for (auto &c : empties) {
if (!state.occ[c.r][c.c]) E_sum += res.next_prob[c.r][c.c];
}
// State更新
state.prob = move(res.next_prob);
state.occ = move(res.next_occ);
}
return E_sum;
}
// スコア計算: round(E_sum * 1e6 / (T-1))
int compute_score(double E) {
return (int)llround(E * 1e6 / (T - 1));
}
int simulate_one(const vector<int>& P) {
uniform_int_distribution<int> dist(0, T-1);
int cur_r = empties[dist(rng)].r;
int cur_c = empties[dist(rng)].c;
vector<vector<bool>> occ(N, vector<bool>(N, false));
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
if (grid[i][j] == '#') occ[i][j] = true;
int steps = 0;
for (int idx : P) {
int dir = rng() % 4;
static int dr[4] = {-1,1,0,0};
static int dc[4] = {0,0,-1,1};
int nr = cur_r, nc = cur_c;
// スライド移動
while (true) {
int ti = nr + dr[dir], tj = nc + dc[dir];
if (ti < 0 || ti >= N || tj < 0 || tj >= N || occ[ti][tj]) break;
nr = ti; nc = tj;
}
cur_r = nr; cur_c = nc;
int br = empties[idx].r, bc = empties[idx].c;
if (cur_r == br && cur_c == bc) break;
occ[br][bc] = true;
steps++;
}
return steps;
}
double estimate(const vector<int>& P, int K) {
ll s = 0;
while (K--) s += simulate_one(P);
return (double)s / K;
}
// Greedy 解法: 各ステップで最もロボット存在確率が小さいセルに岩を配置
// 入力: 初期 State, StepSimulator
// 出力: 貪欲に選んだ配置順序 P (empties のインデックス)
vector<int> greedy_sequence(const StepSimulator::State &init_state, StepSimulator &sim) {
StepSimulator::State state = init_state;
// empties のセル位置からインデックスを引くマップ
unordered_map<long long,int> empty_idx;
for (int k = 0; k < (int)empties.size(); ++k) {
long long key = ((long long)empties[k].r << 32) | (unsigned)empties[k].c;
empty_idx[key] = k;
}
vector<int> P;
P.reserve(empties.size());
// 各ステップで
for (size_t step = 0; step < empties.size(); ++step) {
// 最小確率セルを探索
double best_p = numeric_limits<double>::infinity();
pair<int,int> best_cell = {-1,-1};
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
if (state.prob[i][j] < best_p) {
best_p = state.prob[i][j];
best_cell = {i, j};
}
}
if (best_cell.first < 0) break;
// インデックスを取得して順序に追加
long long key = ((long long)best_cell.first << 32) | (unsigned)best_cell.second;
P.push_back(empty_idx[key]);
// 1ステップ更新
auto res = sim.step(state, best_cell);
state.prob = move(res.next_prob);
state.occ = move(res.next_occ);
}
return P;
}
// Beam Search 解法: 各ステップでトップ A 候補を展開し、スコア上位 B プリフィックスを保持
// 入力:
// init_state: 初期の期待値分布と岩配置マップ
// sim: StepSimulator インスタンス
// A: 各プリフィックスから展開する候補数
// B: 次ステップに残すビーム幅
// 出力:
// 最終的に選んだ配置順序 P (empties のインデックス)
// Beam Search: depth (= 残りステップ数) だけ探索する5引数版
vector<int> beam_search(const StepSimulator::State &init_state,
StepSimulator &sim,
int A, int B,
int depth) {
struct Node {
StepSimulator::State state;
vector<int> P;
double score;
};
int full_T = empties.size();
// (r,c) → empties インデックス
unordered_map<long long,int> empty_idx;
empty_idx.reserve(full_T);
for (int k = 0; k < full_T; ++k) {
long long key = ((long long)empties[k].r << 32) | (unsigned)empties[k].c;
empty_idx[key] = k;
}
// 初期ビーム
vector<Node> beam; beam.reserve(B);
vector<Node> next_beam; next_beam.reserve(B * A);
beam.push_back(Node{init_state, {}, 0.0});
beam[0].P.reserve(depth);
// depth ステップだけ回す
for (int t = 0; t < depth; ++t) {
next_beam.clear();
for (auto &node : beam) {
// 未配置セルから確率が小さい順に上位A件をピック
vector<pair<double,pair<int,int>>> cand;
cand.reserve(full_T);
for (auto &c : empties) {
if (!node.state.occ[c.r][c.c])
cand.emplace_back(node.state.prob[c.r][c.c], make_pair(c.r,c.c));
}
nth_element(cand.begin(),
cand.begin() + min(A,(int)cand.size()),
cand.end(),
[](auto &a, auto &b){ return a.first < b.first; });
cand.resize(min(A,(int)cand.size()));
// 各候補で展開
for (auto &kv : cand) {
auto cell = kv.second;
auto res = sim.step(node.state, cell);
// delta = next_prob の合計
double delta = 0;
for (auto &e : empties) {
if (!node.state.occ[e.r][e.c])
delta += res.next_prob[e.r][e.c];
}
Node nn;
nn.state.prob = move(res.next_prob);
nn.state.occ = move(res.next_occ);
nn.P = node.P;
nn.P.reserve(node.P.size()+1);
long long key = ((long long)cell.first<<32)|(unsigned)cell.second;
nn.P.push_back(empty_idx[key]);
nn.score = node.score + delta;
next_beam.push_back(move(nn));
}
}
// スコア降順で B 件に切り詰め
sort(next_beam.begin(), next_beam.end(),
[](auto &a, auto &b){ return a.score > b.score; });
if ((int)next_beam.size() > B)
next_beam.resize(B);
beam.swap(next_beam);
}
// 最終ビーム内で最良ノードを選択
auto best = max_element(beam.begin(), beam.end(),
[](auto &a, auto &b){ return a.score < b.score; });
return best->P;
}
// next_greedy_step: 現在の State から 1ステップ分貪欲に配置セルを選ぶ
// 確率が同じ場合は、中心に近いセルを優先
int next_greedy_step_mid(const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map) {
const double eps = 1e-12;
double best_p = numeric_limits<double>::infinity();
double best_dist = numeric_limits<double>::infinity();
pair<int,int> best_cell{-1,-1};
// グリッド中心
double ci = (state.prob.size() - 1) / 2.0;
double cj = (state.prob[0].size() - 1) / 2.0;
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
double p = state.prob[i][j];
// マンハッタン距離 or ユークリッド距離
double dist = abs(i - ci) + abs(j - cj);
if (p + eps < best_p ||
(abs(p - best_p) < eps && dist < best_dist)) {
best_p = p;
best_dist = dist;
best_cell = {i, j};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// next_greedy_step: 現在の State から 1ステップ分貪欲に配置セルを選ぶ
// 入力: state, empties, idx_map
// 出力: 選んだ empties のインデックス
int next_greedy_step(const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map) {
double best_p = numeric_limits<double>::infinity();
pair<int,int> best_cell{-1,-1};
for (auto &c : empties) {
if (state.occ[c.r][c.c]) continue;
if (state.prob[c.r][c.c] < best_p) {
best_p = state.prob[c.r][c.c];
best_cell = {c.r, c.c};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// next_greedy_step_outside: 確率が同じなら中心から遠いセルを優先して外側から埋める
int next_greedy_step_outside(const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map) {
const double eps = 1e-12;
double best_p = numeric_limits<double>::infinity();
double best_dist = -1.0; // ← 最遠を探すので初期値は小さく
pair<int,int> best_cell{-1,-1};
double ci = (state.prob.size() - 1) / 2.0;
double cj = (state.prob[0].size() - 1) / 2.0;
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
double p = state.prob[i][j];
double dist = abs(i - ci) + abs(j - cj); // 中心からのマンハッタン距離
if (p + eps < best_p ||
(abs(p - best_p) < eps && dist > best_dist)) {
best_p = p;
best_dist = dist;
best_cell = {i, j};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// next_greedy_step_complex:
// 1) 最小のロボット存在確率 p(i,j) を第一基準に選ぶ
// 2) 同率の場合は、上下左右で「すでに岩が置かれたセル」の数を最も多く持つセルを優先
// 3) さらに同率の場合は、中心からの距離が小さい(中心寄り)セルを優先
int next_greedy_step_complex(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map)
{
const double eps = 1e-12;
double best_p = numeric_limits<double>::infinity();
int best_adj = -1;
double best_dist = numeric_limits<double>::infinity();
pair<int,int> best_cell{-1,-1};
// グリッド中心
double ci = (state.prob.size() - 1) / 2.0;
double cj = (state.prob[0].size() - 1) / 2.0;
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
double p = state.prob[i][j];
// 1) 第一基準: 確率 p(i,j)
if (p > best_p + eps) continue;
// 2) 隣接済みブロック数を数える
int adj = 0;
static int dr[4] = {-1,1,0,0}, dc[4] = {0,0,-1,1};
for (int d = 0; d < 4; ++d) {
int ni = i + dr[d], nj = j + dc[d];
if (ni >= 0 && ni < state.occ.size()
&& nj >= 0 && nj < state.occ.size()
&& state.occ[ni][nj]) {
++adj;
}
}
// 3) 中心からの距離
double dist = fabs(i - ci) + fabs(j - cj);
// 比較: (p, -adj, dist) の三段比較
bool better = false;
if (p + eps < best_p) {
better = true;
} else if (fabs(p - best_p) < eps) {
if (adj > best_adj) {
better = true;
} else if (adj == best_adj) {
if (dist < best_dist - eps) {
better = true;
}
}
}
if (better) {
best_p = p;
best_adj = adj;
best_dist = dist;
best_cell = {i,j};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// next_greedy_step_center_first:
// 1) 中心からの距離を第一優先で最小にするセルを選ぶ
// 2) 同距離の場合は、ロボット存在確率 p(i,j) が小さいセルを優先
// 3) さらに同率の場合は、上下左右の既設ブロック隣接数が多いセルを優先
int next_greedy_step_center_first(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map)
{
const double eps = 1e-12;
double best_dist = numeric_limits<double>::infinity();
double best_p = numeric_limits<double>::infinity();
int best_adj = -1;
pair<int,int> best_cell{-1,-1};
// グリッド中心
double ci = (state.prob.size() - 1) / 2.0;
double cj = (state.prob[0].size() - 1) / 2.0;
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
// 1) 中心からのマンハッタン距離
double dist = fabs(i - ci) + fabs(j - cj);
if (dist > best_dist + eps) continue;
// 2) ロボット存在確率
double p = state.prob[i][j];
// 3) 隣接ブロック数
int adj = 0;
static int dr[4] = {-1,1,0,0}, dc[4] = {0,0,-1,1};
for (int d = 0; d < 4; ++d) {
int ni = i + dr[d], nj = j + dc[d];
if (ni >= 0 && ni < state.occ.size()
&& nj >= 0 && nj < state.occ.size()
&& state.occ[ni][nj]) {
++adj;
}
}
bool better = false;
if (dist + eps < best_dist) {
better = true;
} else if (fabs(dist - best_dist) < eps) {
if (p + eps < best_p) {
better = true;
} else if (fabs(p - best_p) < eps) {
if (adj > best_adj) {
better = true;
}
}
}
if (better) {
best_dist = dist;
best_p = p;
best_adj = adj;
best_cell = {i, j};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// next_greedy_step_custom_outside:
// 1) ロボット存在確率 p(i,j) が最小のセルを選ぶ
// 2) p が同じ場合は、中心からのマンハッタン距離が大きい(外側の)セルを優先
// 3) それも同じ場合は、上下左右に隣接する既設ブロック数が多いセルを優先
int next_greedy_step_custom_outside(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map)
{
const double eps = 1e-12;
double best_p = numeric_limits<double>::infinity();
double best_dist = -1.0; // 外側優先なので初期は小さく
int best_adj = -1;
pair<int,int> best_cell{-1,-1};
// グリッド中心座標
double ci = (state.prob.size()-1) * 0.5;
double cj = (state.prob[0].size()-1) * 0.5;
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
double p = state.prob[i][j];
// 1) 確率で比較
if (p > best_p + eps) continue;
// 2) 中心からのマンハッタン距離(外側優先)
double dist = fabs(i - ci) + fabs(j - cj);
// 3) 隣接ブロック数
int adj = 0;
static int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};
for (int d=0; d<4; ++d) {
int ni=i+dr[d], nj=j+dc[d];
if (ni>=0 && ni<state.occ.size() &&
nj>=0 && nj<state.occ.size() &&
state.occ[ni][nj]) {
++adj;
}
}
bool better = false;
if (p + eps < best_p) {
better = true;
}
else if (fabs(p - best_p) < eps) {
if (dist > best_dist + eps) {
better = true;
}
else if (fabs(dist - best_dist) < eps) {
if (adj > best_adj) {
better = true;
}
}
}
if (better) {
best_p = p;
best_dist = dist;
best_adj = adj;
best_cell = {i,j};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// stepSimulator や next_greedy_step_custom_outside / _inside は既に定義済みとします。
// next_greedy_step_custom_inside:
// 1) ロボット存在確率 p(i,j) が最小のセルを選ぶ
// 2) p が同じ場合は、中心からのマンハッタン距離が小さい(内側の)セルを優先
// 3) さらに同じ場合は、上下左右に隣接する既設ブロック数が多いセルを優先
int next_greedy_step_custom_inside(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map)
{
const double eps = 1e-12;
double best_p = numeric_limits<double>::infinity();
double best_dist = numeric_limits<double>::infinity();
int best_adj = -1;
pair<int,int> best_cell{-1,-1};
// グリッド中心座標
double ci = (state.prob.size() - 1) * 0.5;
double cj = (state.prob[0].size() - 1) * 0.5;
static int dr[4] = {-1,1,0,0}, dc[4] = {0,0,-1,1};
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
double p = state.prob[i][j];
// 1) 確率で比較
if (p > best_p + eps) continue;
// 2) 中心からのマンハッタン距離(内側優先)
double dist = fabs(i - ci) + fabs(j - cj);
// 3) 隣接ブロック数
int adj = 0;
for (int d = 0; d < 4; ++d) {
int ni = i + dr[d], nj = j + dc[d];
if (ni >= 0 && ni < state.occ.size() &&
nj >= 0 && nj < state.occ.size() &&
state.occ[ni][nj]) {
++adj;
}
}
// 総合比較
bool better = false;
if (p + eps < best_p) {
better = true;
}
else if (fabs(p - best_p) < eps) {
if (dist + eps < best_dist) {
better = true;
}
else if (fabs(dist - best_dist) < eps) {
if (adj > best_adj) {
better = true;
}
}
}
if (better) {
best_p = p;
best_dist = dist;
best_adj = adj;
best_cell = {i, j};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// 1…100: 外側優先
// 101…: 10stepごとに inside/outside を切り替え
vector<int> greedy_ring_switch(const StepSimulator::State &init_state,
StepSimulator &sim) {
StepSimulator::State state = init_state;
vector<int> P;
P.reserve(T);
// idx_map 準備
unordered_map<long long,int> idx_map;
idx_map.reserve(T);
for(int k=0;k<T;k++){
long long key = ((long long)empties[k].r<<32)|(unsigned)empties[k].c;
idx_map[key] = k;
}
for(int t = 0; t < T; ++t) {
// どちらの戦略を使うか決定
bool use_outside;
if (t < 1000) {
use_outside = true;
} else {
int phase = ((t - 100) / 1) % 2;
use_outside = (phase == 0); // even → outside, odd → inside
}
// 次に配置するセルを選択
int idx;
if (use_outside) {
idx = next_greedy_step_custom_outside(state, empties, idx_map);
} else {
idx = next_greedy_step_custom_inside(state, empties, idx_map);
}
// 配置
P.push_back(idx);
auto cell = empties[idx];
auto res = sim.step(state, {cell.r, cell.c});
state.prob = move(res.next_prob);
state.occ = move(res.next_occ);
}
return P;
}
// 置いた後の分布の分散(二次モーメント)を計算するヘルパー
double compute_variance(const vector<vector<double>>& prob) {
// グリッド中心 (ci,cj)
double ci = (N-1)*0.5, cj = (N-1)*0.5;
// 期待値(重心)が ci,cj なので分散は E[(x-ci)^2+(y-cj)^2]
double var = 0;
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
double p = prob[i][j];
if(p <= 0) continue;
double di = i - ci;
double dj = j - cj;
var += p * (di*di + dj*dj);
}
}
return var;
}
// next_greedy_step_by_variance:
// 1) p(i,j) が同じなら考慮せずにすべての空セルを候補に
// 2) 各候補 v を置いた場合の next_prob を sim.step で得て
// compute_variance(next_prob) を計算
// 3) その分散 var_v が最大となる v を選択
int next_greedy_step_by_variance(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map,
StepSimulator &sim
) {
int best_idx = -1;
double best_var = -1;
// 各空きセルを試し置き
for(auto &c : empties) {
int i = c.r, j = c.c;
if(state.occ[i][j]) continue;
// 1ステップシミュレーション
auto res = sim.step(state, {i,j});
// 分散を計算
double var = compute_variance(res.next_prob);
// より大きい分散を優先
if (var > best_var) {
best_var = var;
long long key = ((long long)i<<32)|(unsigned)j;
best_idx = idx_map.at(key);
}
}
return best_idx;
}
// 1) 分布のエントロピーを計算するヘルパー
double compute_entropy(const vector<vector<double>>& prob) {
double H = 0;
for(int i = 0; i < N; ++i) {
for(int j = 0; j < N; ++j) {
double p = prob[i][j];
if (p > 0) {
H -= p * log(p);
}
}
}
return H;
}
// 2) next step をエントロピー減少量で選ぶ関数
int next_greedy_step_by_entropy(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map,
StepSimulator &sim
) {
double H0 = compute_entropy(state.prob);
int best_idx = -1;
double best_delta = -1;
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
// 1ステップ後の分布を得る
auto res = sim.step(state, {i,j});
// エントロピーを計算
double H1 = compute_entropy(res.next_prob);
// 減少量 ΔH = H0 - H1 を最大化
double delta = H0 - H1;
if (delta > best_delta) {
best_delta = delta;
long long key = ((long long)i << 32) | (unsigned)j;
best_idx = idx_map.at(key);
}
}
return best_idx;
}
// 外側偏重:p/(dist+eps) を最小化
int next_greedy_step_ratio_outside(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map
) {
const double eps = 1e-6;
double best_score = numeric_limits<double>::infinity();
int best_adj = -1;
pair<int,int> best_cell{-1,-1};
double ci = (state.prob.size()-1)*0.5;
double cj = (state.prob[0].size()-1)*0.5;
static int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};
for(auto &c : empties){
int i = c.r, j = c.c;
if(state.occ[i][j]) continue;
double p = state.prob[i][j];
double dist = fabs(i - ci) + fabs(j - cj);
double score = p / (dist + eps);
// 隣接岩数
int adj = 0;
for(int d=0; d<4; d++){
int ni = i + dr[d], nj = j + dc[d];
if(ni>=0 && ni<state.occ.size() &&
nj>=0 && nj<state.occ.size() &&
state.occ[ni][nj]) {
++adj;
}
}
bool better = false;
if(score < best_score){
better = true;
} else if(fabs(score - best_score) < 1e-12 && adj > best_adj){
better = true;
}
if(better){
best_score = score;
best_adj = adj;
best_cell = {i,j};
}
}
long long key = ((long long)best_cell.first<<32)|(unsigned)best_cell.second;
return idx_map.at(key);
}
// 必要なユーティリティ:スライド先テーブルの構築
vector<array<int,4>> build_slide_to(const vector<vector<bool>>& occ){
vector<array<int,4>> slide_to(N*N);
static int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};
for(int i=0;i<N;i++){
for(int j=0;j<N;j++){
int u = i*N + j;
if(occ[i][j]){
slide_to[u] = {u,u,u,u};
continue;
}
for(int d=0;d<4;d++){
int ni=i, nj=j;
while(true){
int ti = ni+dr[d], tj = nj+dc[d];
if(ti<0||ti>=N||tj<0||tj>=N||occ[ti][tj]) break;
ni=ti; nj=tj;
}
slide_to[u][d] = ni*N + nj;
}
}
}
return slide_to;
}
// 拡張版:複数指標(p, dist, adj, flow, grad)で候補を選ぶ
int next_greedy_step_enhanced(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map,
StepSimulator &sim
) {
// 1) スライド先 & flow の事前計算
auto slide_to = build_slide_to(state.occ);
vector<ll> flow(N*N, 0);
for(int u=0; u<N*N; ++u){
int ui=u/N, uj=u%N;
if(state.occ[ui][uj]) continue;
for(int d=0; d<4; ++d){
int v = slide_to[u][d];
if(!state.occ[v/N][v%N]) flow[v]++;
}
}
// 2) grad(確率勾配)の計算
vector<double> grad(N*N, 0.0);
static int dr[4]={-1,1,0,0}, dc[4]={0,0,-1,1};
for(auto &c : empties){
int i=c.r, j=c.c;
if(state.occ[i][j]) continue;
double g=0;
double p = state.prob[i][j];
for(int d=0;d<4;d++){
int ni=i+dr[d], nj=j+dc[d];
if(ni<0||ni>=N||nj<0||nj>=N||state.occ[ni][nj]) continue;
g += fabs(p - state.prob[ni][nj]);
}
grad[i*N+j] = g;
}
// 3) 候補選定:lex 比較
const double eps = 1e-12;
double ci = (N-1)*0.5, cj = (N-1)*0.5;
double best_p = numeric_limits<double>::infinity();
double best_dist = -1.0;
int best_adj = -1;
ll best_flow = -1;
double best_grad = -1.0;
pair<int,int> best_cell{-1,-1};
for(auto &c : empties){
int i=c.r, j=c.c;
if(state.occ[i][j]) continue;
double p = state.prob[i][j];
if(p > best_p + eps) continue;
double dist = fabs(i - ci) + fabs(j - cj);
int adj = 0;
for(int d=0;d<4;d++){
int ni=i+dr[d], nj=j+dc[d];
if(ni>=0&&ni<N&&nj>=0&&nj<N&&state.occ[ni][nj]) adj++;
}
ll f = flow[i*N+j];
double g = grad[i*N+j];
bool better = false;
if (p + eps < best_p) {
better = true;
} else if (fabs(p - best_p) < eps) {
if (dist > best_dist + eps) {
better = true;
} else if (fabs(dist - best_dist) < eps) {
if (adj > best_adj) {
better = true;
} else if (adj == best_adj) {
if (f > best_flow) {
better = true;
} else if (f == best_flow) {
if (g > best_grad + eps) {
better = true;
}
}
}
}
}
if (better) {
best_p = p;
best_dist = dist;
best_adj = adj;
best_flow = f;
best_grad = g;
best_cell = {i,j};
}
}
long long key = ((long long)best_cell.first<<32)|(unsigned)best_cell.second;
return idx_map.at(key);
}
int next_greedy_step_adjprob(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map
) {
const double eps = 1e-12;
// STEP1: 最小 p を見つける
double best_p = numeric_limits<double>::infinity();
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
best_p = min(best_p, state.prob[i][j]);
}
// STEP2: 最小 p のセルの中で、
// - まず「隣接確率和 adj_sum」を最大化、
// - さらに adj_sum が同じなら「隣接最大値 adj_max」を最大化
static int dr[4] = {-1,1,0,0}, dc[4] = {0,0,-1,1};
double best_adj_sum = -1.0;
double best_adj_max = -1.0;
pair<int,int> best_cell{-1,-1};
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
double p = state.prob[i][j];
if (fabs(p - best_p) > eps) continue;
// 隣接和と隣接最大値を計算
double adj_sum = 0.0, adj_max = 0.0;
for (int d = 0; d < 4; ++d) {
int ni = i + dr[d], nj = j + dc[d];
if (ni >= 0 && ni < N && nj >= 0 && nj < N && !state.occ[ni][nj]) {
double q = state.prob[ni][nj];
adj_sum += q;
adj_max = max(adj_max, q);
}
}
// 比較:まず adj_sum、同値なら adj_max
if (adj_sum > best_adj_sum + eps ||
(fabs(adj_sum - best_adj_sum) < eps && adj_max > best_adj_max + eps)) {
best_adj_sum = adj_sum;
best_adj_max = adj_max;
best_cell = {i, j};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// 1) p(i,j) が最小のセルを絞り込み
// 2) その中で、上下左右4近傍の最大確率 adj_max を最大化
// 3) それでも並んだら、中心からのマンハッタン距離 dist を最大化(外側優先)
int next_greedy_step_adjmax_outside(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map
) {
const double eps = 1e-12;
// STEP1: 最小 p を求める
double min_p = numeric_limits<double>::infinity();
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
min_p = min(min_p, state.prob[i][j]);
}
// グリッド中心
double ci = (N - 1) * 0.5;
double cj = (N - 1) * 0.5;
static int dr[4] = {-1,1,0,0}, dc[4] = {0,0,-1,1};
double best_adj_max = -1.0;
double best_dist = -1.0;
pair<int,int> best_cell{-1,-1};
// STEP2 & 3: min_pセルの中で adj_max→dist の順で選ぶ
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
double p = state.prob[i][j];
if (fabs(p - min_p) > eps) continue;
// 隣接最大値を計算
double local_max = 0;
for (int d = 0; d < 4; ++d) {
int ni = i + dr[d], nj = j + dc[d];
if (ni >= 0 && ni < N && nj >= 0 && nj < N && !state.occ[ni][nj]) {
local_max = max(local_max, state.prob[ni][nj]);
}
}
// 中心からのマンハッタン距離
double dist = fabs(i - ci) + fabs(j - cj);
// 比較: adj_max ↑, dist ↑
if (local_max > best_adj_max + eps ||
(fabs(local_max - best_adj_max) < eps && dist > best_dist + eps)) {
best_adj_max = local_max;
best_dist = dist;
best_cell = {i, j};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// 1) p(i,j) が最小のセルを絞り込み
// 2) その中で、上下左右4近傍の最大確率 adj_max を最大化
// 3) それでも並んだら、中心からのマンハッタン距離 dist を最小化(内側優先)
int next_greedy_step_adjmax_inside(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map
) {
const double eps = 1e-12;
// STEP1: 最小 p を求める
double min_p = numeric_limits<double>::infinity();
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
min_p = min(min_p, state.prob[i][j]);
}
// グリッド中心
double ci = (N - 1) * 0.5;
double cj = (N - 1) * 0.5;
static int dr[4] = {-1,1,0,0}, dc[4] = {0,0,-1,1};
double best_adj_max = -1.0;
double best_dist = numeric_limits<double>::infinity();
pair<int,int> best_cell{-1,-1};
// STEP2 & 3: min_pセルの中で adj_max→dist(inward) の順で選ぶ
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
double p = state.prob[i][j];
if (fabs(p - min_p) > eps) continue;
// 隣接最大値を計算
double local_max = 0;
for (int d = 0; d < 4; ++d) {
int ni = i + dr[d], nj = j + dc[d];
if (ni >= 0 && ni < N && nj >= 0 && nj < N && !state.occ[ni][nj]) {
local_max = max(local_max, state.prob[ni][nj]);
}
}
// 中心からのマンハッタン距離
double dist = fabs(i - ci) + fabs(j - cj);
// 比較: adj_max ↑, dist ↓
if (local_max > best_adj_max + eps ||
(fabs(local_max - best_adj_max) < eps && dist + eps < best_dist)) {
best_adj_max = local_max;
best_dist = dist;
best_cell = {i, j};
}
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// 1) p(i,j) が最小のセルを絞り込み
// 2) その中で、上下左右4近傍の最大確率 adj_max を最大化
// 3) それでも並んだら、
// 置いたあとにその adj_max セルの「最大スライド距離」が
// どれだけ減るか(減少量)を最大化
// 1) p(i,j) が最小のセルを絞り込み
// 2) その中で、上下左右4近傍の最大確率 adj_max を最大化
// 3) 置いたときにその adj_max セルの「最大スライド距離」が最も減るセルを選ぶ
int next_greedy_step_adjmax_trap(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map
) {
const double eps = 1e-12;
int N = state.prob.size();
static int dr[4] = {-1,1,0,0}, dc[4] = {0,0,-1,1};
// STEP1: 最小 p を求める
double min_p = numeric_limits<double>::infinity();
for (auto &c : empties) if (!state.occ[c.r][c.c])
min_p = min(min_p, state.prob[c.r][c.c]);
// STEP2: min_p セルの中で隣接最大 prob を求め候補リストに
double best_adj_max = -1.0;
vector<Cell> cand;
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j] || fabs(state.prob[i][j] - min_p) > eps) continue;
double local_max = 0;
for (int d=0; d<4; ++d) {
int ni=i+dr[d], nj=j+dc[d];
if (ni>=0&&ni<N&&nj>=0&&nj<N&&!state.occ[ni][nj])
local_max = max(local_max, state.prob[ni][nj]);
}
if (local_max > best_adj_max + eps) {
best_adj_max = local_max;
cand.clear();
cand.push_back(c);
} else if (fabs(local_max - best_adj_max) < eps) {
cand.push_back(c);
}
}
// STEP3: それらをトラップ効果で選別
auto slide_len = [&](int si, int sj, const vector<vector<bool>>& occ_map){
int maxd=0;
for(int d=0;d<4;d++){
int dist=0, ni=si, nj=sj;
while(true){
int ti=ni+dr[d], tj=nj+dc[d];
if(ti<0||ti>=N||tj<0||tj>=N||occ_map[ti][tj]) break;
ni=ti; nj=tj; ++dist;
}
maxd = max(maxd, dist);
}
return maxd;
};
double best_reduction = -1.0;
pair<int,int> best_cell{-1,-1};
for (auto &c : cand) {
int i=c.r, j=c.c;
// adj_max セルを同様に見つける
double local_max=0; pair<int,int> target{-1,-1};
for(int d=0;d<4;d++){
int ni=i+dr[d], nj=j+dc[d];
if(ni>=0&&ni<N&&nj>=0&&nj<N&&!state.occ[ni][nj]){
double q = state.prob[ni][nj];
if (q > local_max + eps) {
local_max = q;
target = {ni,nj};
}
}
}
if (target.first<0) continue;
double orig = slide_len(target.first, target.second, state.occ);
auto occ2 = state.occ;
occ2[i][j] = true;
double now = slide_len(target.first, target.second, occ2);
double red = orig - now;
if (red > best_reduction + eps) {
best_reduction = red;
best_cell = {i,j};
}
}
// フォールバック: 候補なしなら outside 戦略に
if (best_cell.first < 0) {
return next_greedy_step_adjmax_outside(state, empties, idx_map);
}
long long key = ((long long)best_cell.first << 32)
| (unsigned)best_cell.second;
return idx_map.at(key);
}
// 1) p(i,j) が最小のセルを絞り込み
// 2) その中で、上下左右4近傍の最大確率 adj_max を最大化
// 3) 置いたときにその adj_max セルの「最大スライド距離」が最も減るセルを絞り込み
// 4) さらにその中で、上下左右4近傍の「空きマス数」が最大のセルを選ぶ
int next_greedy_step_trap_chain(
const StepSimulator::State &state,
const vector<Cell> &empties,
const unordered_map<long long,int> &idx_map
) {
const double eps = 1e-12;
int N = state.prob.size();
static int dr[4] = {-1,1,0,0}, dc[4] = {0,0,-1,1};
// STEP1: 最小 p を求める
double min_p = numeric_limits<double>::infinity();
for (auto &c : empties) {
if (state.occ[c.r][c.c]) continue;
min_p = min(min_p, state.prob[c.r][c.c]);
}
// STEP2: min_p セルの中で adj_max を最大化→一時候補
double best_adj_max = -1.0;
vector<Cell> level2;
for (auto &c : empties) {
int i = c.r, j = c.c;
if (state.occ[i][j]) continue;
if (fabs(state.prob[i][j] - min_p) > eps) continue;
double local_max = 0.0;
for (int d=0; d<4; ++d) {
int ni = i+dr[d], nj = j+dc[d];
if (ni>=0&&ni<N&&nj>=0&&nj<N&&!state.occ[ni][nj])
local_max = max(local_max, state.prob[ni][nj]);
}
if (local_max > best_adj_max + eps) {
best_adj_max = local_max;
level2.clear();
level2.push_back(c);
} else if (fabs(local_max - best_adj_max) < eps) {
level2.push_back(c);
}
}
// helper: compute slide length
auto slide_len = [&](int si,int sj,const vector<vector<bool>>& occ_map){
int maxd = 0;
for(int d=0;d<4;d++){
int dist=0, ni=si, nj=sj;
while(true){
int ti=ni+dr[d], tj=nj+dc[d];
if(ti<0||ti>=N||tj<0||tj>=N||occ_map[ti][tj]) break;
ni=ti; nj=tj; ++dist;
}
maxd = max(maxd, dist);
}
return maxd;
};
// STEP3: trap reduction 最大化 →さらに候補絞り
double best_reduction = -1.0;
vector<Cell> level3;
for (auto &c : level2) {
int i = c.r, j = c.c;
// 隣接 max セルを探す
double local_max=0; pair<int,int> tgt{-1,-1};
for(int d=0;d<4;d++){
int ni=i+dr[d], nj=j+dc[d];
if(ni>=0&&ni<N&&nj>=0&&nj<N&&!state.occ[ni][nj]){
double q = state.prob[ni][nj];
if(q > local_max + eps){
local_max = q;
tgt = {ni,nj};
}
}
}
if(tgt.first<0) continue;
double orig = slide_len(tgt.first, tgt.second, state.occ);
auto occ2 = state.occ;
occ2[i][j] = true;
double now = slide_len(tgt.first, tgt.second, occ2);
double red = orig - now;
if (red > best_reduction + eps) {
best_reduction = red;
level3.clear();
level3.push_back(c);
} else if (fabs(red - best_reduction) < eps) {
level3.push_back(c);
}
}
// STEP4: 空きマス隣接数 最大化
int best_empty_adj = -1;
pair<int,int> best_cell{-1,-1};
for (auto &c : level3) {
int i = c.r, j = c.c;
int empty_adj = 0;
for(int d=0;d<4;d++){
int ni=i+dr[d], nj=j+dc[d];
if(ni>=0&&ni<N&&nj>=0&&nj<N&&!state.occ[ni][nj]) ++empty_adj;
}
if (empty_adj > best_empty_adj) {
best_empty_adj = empty_adj;
best_cell = {i,j};
}
}
// フォールバック: もし候補なしなら outside 戦略
if (best_cell.first < 0) {
return next_greedy_step_adjmax_outside(state, empties, idx_map);
}
ll key = ((ll)best_cell.first<<32) | (unsigned)best_cell.second;
return idx_map.at(key);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
// --- 入力読み込み ---
cin >> N >> M;
grid.resize(N);
for(int i = 0; i < N; i++){
cin >> grid[i];
}
// --- 空セルリストとマップ構築 ---
empties.clear();
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
if(grid[i][j] == '.') empties.push_back({i,j});
}
}
T = empties.size();
unordered_map<long long,int> idx_map;
idx_map.reserve(T);
for(int k = 0; k < T; k++){
long long key = ((long long)empties[k].r<<32)|(unsigned)empties[k].c;
idx_map[key] = k;
}
// --- 初期 State 構築 ---
vector<vector<double>> prob(N, vector<double>(N,0.0));
vector<vector<bool>> occ (N, vector<bool>(N,false));
double p0 = 1.0 / T;
for(auto &c: empties) prob[c.r][c.c] = p0;
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
if(grid[i][j] == '#') occ[i][j] = true;
}
}
StepSimulator sim(N);
StepSimulator::State init{prob, occ};
double bestE = -1.0;
vector<int> bestP;
// --- Greedy inside ---
{
auto state = init;
vector<int> P;
P.reserve(T);
for(int t = 0; t < T; t++){
int idx = next_greedy_step_adjmax_inside(state, empties, idx_map);
P.push_back(idx);
auto cell = empties[idx];
auto res = sim.step(state, {cell.r, cell.c});
state.prob = move(res.next_prob);
state.occ = move(res.next_occ);
}
double E = compute_expected_sum(P);
if(E > bestE){
bestE = E;
bestP = move(P);
}
}
// --- Greedy outside ---
{
auto state = init;
vector<int> P;
P.reserve(T);
for(int t = 0; t < T; t++){
int idx = next_greedy_step_adjmax_outside(state, empties, idx_map);
P.push_back(idx);
auto cell = empties[idx];
auto res = sim.step(state, {cell.r, cell.c});
state.prob = move(res.next_prob);
state.occ = move(res.next_occ);
}
double E = compute_expected_sum(P);
if(E > bestE){
bestE = E;
bestP = move(P);
}
}
// --- Greedy sum_max (adjprob) ---
{
auto state = init;
vector<int> P;
P.reserve(T);
for(int t = 0; t < T; t++){
int idx = next_greedy_step_adjprob(state, empties, idx_map);
P.push_back(idx);
auto cell = empties[idx];
auto res = sim.step(state, {cell.r, cell.c});
state.prob = move(res.next_prob);
state.occ = move(res.next_occ);
}
double E = compute_expected_sum(P);
if(E > bestE){
bestE = E;
bestP = move(P);
}
}
// --- Greedy sum_max (adjprob) ---
{
auto state = init;
vector<int> P;
P.reserve(T);
for(int t = 0; t < T; t++){
int idx = next_greedy_step_trap_chain(state, empties, idx_map);
P.push_back(idx);
auto cell = empties[idx];
auto res = sim.step(state, {cell.r, cell.c});
state.prob = move(res.next_prob);
state.occ = move(res.next_occ);
}
double E = compute_expected_sum(P);
if(E > bestE){
bestE = E;
bestP = move(P);
}
}
// --- 出力 ---
for(int idx : bestP){
cout << empties[idx].r << " " << empties[idx].c << "\n";
}
cerr << "Best E = " << fixed << setprecision(6) << bestE
<< ", score = " << compute_score(bestE) << "\n";
return 0;
}
提出情報
| 提出日時 |
|
| 問題 |
A - Gamble on Ice |
| ユーザ |
koshinM |
| 言語 |
C++ 17 (gcc 12.2) |
| 得点 |
145375933 |
| コード長 |
49719 Byte |
| 結果 |
AC |
| 実行時間 |
397 ms |
| メモリ |
4204 KiB |
コンパイルエラー
Main.cpp: In function ‘int next_greedy_step_complex(const StepSimulator::State&, const std::vector<Cell>&, const std::unordered_map<long long int, int>&)’:
Main.cpp:378:31: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
378 | if (ni >= 0 && ni < state.occ.size()
| ~~~^~~~~~~~~~~~~~~~~~
Main.cpp:379:31: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
379 | && nj >= 0 && nj < state.occ.size()
| ~~~^~~~~~~~~~~~~~~~~~
Main.cpp: In function ‘int next_greedy_step_center_first(const StepSimulator::State&, const std::vector<Cell>&, const std::unordered_map<long long int, int>&)’:
Main.cpp:448:31: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
448 | if (ni >= 0 && ni < state.occ.size()
| ~~~^~~~~~~~~~~~~~~~~~
Main.cpp:449:31: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
449 | && nj >= 0 && nj < state.occ.size()
| ~~~^~~~~~~~~~~~~~~~~~
Main.cpp: In function ‘int next_greedy_step_custom_outside(const StepSimulator::State&, const std::vector<Cell>&, const std::unordered_map<long long int, int>&)’:
Main.cpp:516:28: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
516 | if (ni>=0 && ni<state.occ.size() &&
| ~~^~~~~~~~~~~~~~~~~
Main.cpp:517:28: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
517 | nj>=0 && nj<state.occ.size() &&
| ~~^~~~~~~~~~~~~~~~~
Main.cpp: In function ‘int next_greedy_step_custom_inside(const StepSimulator::State&, const std::vector<Cell>&, const std::unordered_map<long long int, int>&)’:
Main.cpp:588:31: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
588 | if (ni >= 0 && ni < state.occ.size() &&
| ~~~^~~~~~~~~~~~~~~~~~
Main.cpp:589:31: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
589 | nj >= 0 && nj < state.occ.size() &&
| ~~~^~~~~~~~~~~~~~~~~~
Main.cpp: In function ‘int next_greedy_step_ratio_outside(const StepSimulator::State&, const std::vector<Cell>&, const std::unordered_map<long long int, int>&)’:
Main.cpp:792:27: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
792 | if(ni>=0 && ni<state.occ.size() &&
| ~~^~~~~~~~~~~~~~~~~
Main.cpp:793:27: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::vector<bool> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
793 | nj>=0 && nj<state.occ.size() &&
| ~~^~~~~~~~~~~~~~~~~
Main.cpp: In function ‘int next_greedy_step_enhanced(const StepSimulator::State&, const std::vector<Cell>&, const std::unordered_map<long long int, int>&, StepSimulator&)’:
Main.cpp:847:33: warning: unused parameter ‘sim’ [-Wunused-parameter]
847 | StepSimulator &sim
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~
ジャッジ結果
| セット名 |
test_ALL |
| 得点 / 配点 |
145375933 / 150000000 |
| 結果 |
|
| セット名 |
テストケース |
| 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_0100.txt, test_0101.txt, test_0102.txt, test_0103.txt, test_0104.txt, test_0105.txt, test_0106.txt, test_0107.txt, test_0108.txt, test_0109.txt, test_0110.txt, test_0111.txt, test_0112.txt, test_0113.txt, test_0114.txt, test_0115.txt, test_0116.txt, test_0117.txt, test_0118.txt, test_0119.txt, test_0120.txt, test_0121.txt, test_0122.txt, test_0123.txt, test_0124.txt, test_0125.txt, test_0126.txt, test_0127.txt, test_0128.txt, test_0129.txt, test_0130.txt, test_0131.txt, test_0132.txt, test_0133.txt, test_0134.txt, test_0135.txt, test_0136.txt, test_0137.txt, test_0138.txt, test_0139.txt, test_0140.txt, test_0141.txt, test_0142.txt, test_0143.txt, test_0144.txt, test_0145.txt, test_0146.txt, test_0147.txt, test_0148.txt, test_0149.txt |
| ケース名 |
結果 |
実行時間 |
メモリ |
| test_0000.txt |
AC |
397 ms |
3984 KiB |
| test_0001.txt |
AC |
336 ms |
4060 KiB |
| test_0002.txt |
AC |
369 ms |
4064 KiB |
| test_0003.txt |
AC |
335 ms |
4184 KiB |
| test_0004.txt |
AC |
367 ms |
4176 KiB |
| test_0005.txt |
AC |
384 ms |
4020 KiB |
| test_0006.txt |
AC |
379 ms |
3968 KiB |
| test_0007.txt |
AC |
352 ms |
3960 KiB |
| test_0008.txt |
AC |
388 ms |
4064 KiB |
| test_0009.txt |
AC |
383 ms |
4036 KiB |
| test_0010.txt |
AC |
348 ms |
3968 KiB |
| test_0011.txt |
AC |
395 ms |
4024 KiB |
| test_0012.txt |
AC |
370 ms |
4184 KiB |
| test_0013.txt |
AC |
380 ms |
4072 KiB |
| test_0014.txt |
AC |
381 ms |
3968 KiB |
| test_0015.txt |
AC |
366 ms |
3964 KiB |
| test_0016.txt |
AC |
373 ms |
4192 KiB |
| test_0017.txt |
AC |
346 ms |
4132 KiB |
| test_0018.txt |
AC |
321 ms |
4036 KiB |
| test_0019.txt |
AC |
370 ms |
3960 KiB |
| test_0020.txt |
AC |
381 ms |
4180 KiB |
| test_0021.txt |
AC |
363 ms |
4028 KiB |
| test_0022.txt |
AC |
367 ms |
4012 KiB |
| test_0023.txt |
AC |
378 ms |
4140 KiB |
| test_0024.txt |
AC |
329 ms |
4172 KiB |
| test_0025.txt |
AC |
373 ms |
4180 KiB |
| test_0026.txt |
AC |
384 ms |
4196 KiB |
| test_0027.txt |
AC |
383 ms |
4136 KiB |
| test_0028.txt |
AC |
360 ms |
4200 KiB |
| test_0029.txt |
AC |
373 ms |
4060 KiB |
| test_0030.txt |
AC |
394 ms |
4140 KiB |
| test_0031.txt |
AC |
355 ms |
4016 KiB |
| test_0032.txt |
AC |
335 ms |
4140 KiB |
| test_0033.txt |
AC |
360 ms |
4180 KiB |
| test_0034.txt |
AC |
336 ms |
3972 KiB |
| test_0035.txt |
AC |
330 ms |
3956 KiB |
| test_0036.txt |
AC |
377 ms |
3964 KiB |
| test_0037.txt |
AC |
375 ms |
4180 KiB |
| test_0038.txt |
AC |
328 ms |
4056 KiB |
| test_0039.txt |
AC |
361 ms |
4060 KiB |
| test_0040.txt |
AC |
352 ms |
4016 KiB |
| test_0041.txt |
AC |
309 ms |
4124 KiB |
| test_0042.txt |
AC |
349 ms |
3960 KiB |
| test_0043.txt |
AC |
352 ms |
4028 KiB |
| test_0044.txt |
AC |
371 ms |
4060 KiB |
| test_0045.txt |
AC |
377 ms |
4184 KiB |
| test_0046.txt |
AC |
366 ms |
3964 KiB |
| test_0047.txt |
AC |
319 ms |
4136 KiB |
| test_0048.txt |
AC |
386 ms |
4204 KiB |
| test_0049.txt |
AC |
366 ms |
4080 KiB |
| test_0050.txt |
AC |
325 ms |
4172 KiB |
| test_0051.txt |
AC |
365 ms |
4132 KiB |
| test_0052.txt |
AC |
384 ms |
4176 KiB |
| test_0053.txt |
AC |
336 ms |
4024 KiB |
| test_0054.txt |
AC |
395 ms |
4024 KiB |
| test_0055.txt |
AC |
313 ms |
4180 KiB |
| test_0056.txt |
AC |
364 ms |
4136 KiB |
| test_0057.txt |
AC |
357 ms |
4132 KiB |
| test_0058.txt |
AC |
337 ms |
4132 KiB |
| test_0059.txt |
AC |
349 ms |
4016 KiB |
| test_0060.txt |
AC |
388 ms |
4168 KiB |
| test_0061.txt |
AC |
320 ms |
4164 KiB |
| test_0062.txt |
AC |
385 ms |
4032 KiB |
| test_0063.txt |
AC |
383 ms |
4020 KiB |
| test_0064.txt |
AC |
352 ms |
4180 KiB |
| test_0065.txt |
AC |
391 ms |
3968 KiB |
| test_0066.txt |
AC |
384 ms |
3968 KiB |
| test_0067.txt |
AC |
378 ms |
4144 KiB |
| test_0068.txt |
AC |
360 ms |
4144 KiB |
| test_0069.txt |
AC |
390 ms |
4144 KiB |
| test_0070.txt |
AC |
376 ms |
3968 KiB |
| test_0071.txt |
AC |
315 ms |
4168 KiB |
| test_0072.txt |
AC |
379 ms |
4140 KiB |
| test_0073.txt |
AC |
317 ms |
4132 KiB |
| test_0074.txt |
AC |
389 ms |
4032 KiB |
| test_0075.txt |
AC |
317 ms |
4128 KiB |
| test_0076.txt |
AC |
385 ms |
3976 KiB |
| test_0077.txt |
AC |
309 ms |
3956 KiB |
| test_0078.txt |
AC |
332 ms |
4052 KiB |
| test_0079.txt |
AC |
382 ms |
4132 KiB |
| test_0080.txt |
AC |
381 ms |
4184 KiB |
| test_0081.txt |
AC |
331 ms |
4008 KiB |
| test_0082.txt |
AC |
393 ms |
4036 KiB |
| test_0083.txt |
AC |
326 ms |
4016 KiB |
| test_0084.txt |
AC |
312 ms |
4020 KiB |
| test_0085.txt |
AC |
358 ms |
4024 KiB |
| test_0086.txt |
AC |
364 ms |
3964 KiB |
| test_0087.txt |
AC |
338 ms |
4020 KiB |
| test_0088.txt |
AC |
390 ms |
4052 KiB |
| test_0089.txt |
AC |
369 ms |
3964 KiB |
| test_0090.txt |
AC |
329 ms |
4164 KiB |
| test_0091.txt |
AC |
310 ms |
4064 KiB |
| test_0092.txt |
AC |
369 ms |
3972 KiB |
| test_0093.txt |
AC |
375 ms |
3968 KiB |
| test_0094.txt |
AC |
392 ms |
4148 KiB |
| test_0095.txt |
AC |
346 ms |
4132 KiB |
| test_0096.txt |
AC |
364 ms |
4136 KiB |
| test_0097.txt |
AC |
313 ms |
4008 KiB |
| test_0098.txt |
AC |
329 ms |
3976 KiB |
| test_0099.txt |
AC |
352 ms |
4188 KiB |
| test_0100.txt |
AC |
380 ms |
4136 KiB |
| test_0101.txt |
AC |
363 ms |
4128 KiB |
| test_0102.txt |
AC |
387 ms |
4184 KiB |
| test_0103.txt |
AC |
349 ms |
4044 KiB |
| test_0104.txt |
AC |
323 ms |
4012 KiB |
| test_0105.txt |
AC |
356 ms |
4136 KiB |
| test_0106.txt |
AC |
394 ms |
4032 KiB |
| test_0107.txt |
AC |
368 ms |
4180 KiB |
| test_0108.txt |
AC |
379 ms |
4184 KiB |
| test_0109.txt |
AC |
337 ms |
4012 KiB |
| test_0110.txt |
AC |
359 ms |
3980 KiB |
| test_0111.txt |
AC |
383 ms |
4184 KiB |
| test_0112.txt |
AC |
383 ms |
3964 KiB |
| test_0113.txt |
AC |
374 ms |
4176 KiB |
| test_0114.txt |
AC |
358 ms |
4136 KiB |
| test_0115.txt |
AC |
351 ms |
4032 KiB |
| test_0116.txt |
AC |
385 ms |
4020 KiB |
| test_0117.txt |
AC |
373 ms |
4132 KiB |
| test_0118.txt |
AC |
367 ms |
4132 KiB |
| test_0119.txt |
AC |
352 ms |
4012 KiB |
| test_0120.txt |
AC |
308 ms |
4016 KiB |
| test_0121.txt |
AC |
386 ms |
4016 KiB |
| test_0122.txt |
AC |
349 ms |
4132 KiB |
| test_0123.txt |
AC |
327 ms |
4124 KiB |
| test_0124.txt |
AC |
328 ms |
4012 KiB |
| test_0125.txt |
AC |
345 ms |
4016 KiB |
| test_0126.txt |
AC |
353 ms |
4060 KiB |
| test_0127.txt |
AC |
348 ms |
4024 KiB |
| test_0128.txt |
AC |
346 ms |
4176 KiB |
| test_0129.txt |
AC |
382 ms |
4180 KiB |
| test_0130.txt |
AC |
346 ms |
4024 KiB |
| test_0131.txt |
AC |
334 ms |
4020 KiB |
| test_0132.txt |
AC |
327 ms |
4020 KiB |
| test_0133.txt |
AC |
322 ms |
4172 KiB |
| test_0134.txt |
AC |
325 ms |
4168 KiB |
| test_0135.txt |
AC |
314 ms |
4008 KiB |
| test_0136.txt |
AC |
366 ms |
4164 KiB |
| test_0137.txt |
AC |
358 ms |
4136 KiB |
| test_0138.txt |
AC |
336 ms |
4008 KiB |
| test_0139.txt |
AC |
385 ms |
4132 KiB |
| test_0140.txt |
AC |
354 ms |
4012 KiB |
| test_0141.txt |
AC |
321 ms |
4128 KiB |
| test_0142.txt |
AC |
382 ms |
3968 KiB |
| test_0143.txt |
AC |
363 ms |
3964 KiB |
| test_0144.txt |
AC |
374 ms |
4136 KiB |
| test_0145.txt |
AC |
390 ms |
4140 KiB |
| test_0146.txt |
AC |
367 ms |
4068 KiB |
| test_0147.txt |
AC |
333 ms |
4180 KiB |
| test_0148.txt |
AC |
357 ms |
4024 KiB |
| test_0149.txt |
AC |
359 ms |
4020 KiB |