結果
| 問題 |
No.5022 XOR Printer
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-07-26 16:32:41 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
MLE
|
| 実行時間 | - |
| コード長 | 4,870 bytes |
| コンパイル時間 | 6,394 ms |
| コンパイル使用メモリ | 337,056 KB |
| 実行使用メモリ | 716,448 KB |
| スコア | 0 |
| 最終ジャッジ日時 | 2025-07-26 16:33:40 |
| 合計ジャッジ時間 | 13,634 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge1 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | TLE * 12 MLE * 2 -- * 36 |
ソースコード
// #define _GLIBCXX_DEBUG
#pragma GCC optimize("O3")
// #pragma GCC optimize("O2")
#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <atcoder/all>
using namespace std;
using namespace atcoder;
using ll = long long;
#define rep(i,n) for (ll i = 0; i < (n); ++i)
using vl = vector<ll>;
using vvl = vector<vl>;
using P = pair<ll,ll>;
#define pb push_back
#define int long long
// #define double long double
#define INF (ll) 3e18
// Ctrl + Shift + B コンパイル
// Ctrl + C 中断
// ./m 実行
// No.5022 XOR Printer
int N = 10;
int T = 1000;
vvl a(10, vl(10));
void input() {
cin >> N >> T;
rep(i, 10) rep(j, 10) cin >> a[i][j];
}
int score() {
int res = 0;
for(auto x : a) for(auto y : x) res += y;
return res;
}
vector<P> move_log;
string move_cycle;
void init(){
// 経路を決め打ってしまおう
for(int j = 1; j < 10; j++) {
move_cycle.push_back('R');
move_log.emplace_back(0, j);
}
for(int i = 1; i < 10; i++){
if(i % 2) {
move_cycle.push_back('D');
for(int j = 9; j >= 1; j--){
move_log.emplace_back(i, j);
if(j != 1) move_cycle.push_back('L');
}
} else {
move_cycle.push_back('D');
for(int j = 1; j < 10; j++){
move_log.emplace_back(i, j);
if(j != 9) move_cycle.push_back('R');
}
}
}
move_cycle.push_back('L');
for(int i = 9; i >= 0; i--) {
move_log.emplace_back(i, 0);
if(i != 0) move_cycle.push_back('U');
}
assert(move_log.size() == 100);
assert(move_cycle.size() == 100);
{
const int REPEAT = 10; // 追加で 10 回複製 → 11 周分
vector<P> base_move = move_log; // 元の 100 要素を退避
string base_cycle = move_cycle;
for(int r = 0; r < REPEAT; ++r){
move_log.insert(move_log.end(), base_move.begin(), base_move.end());
move_cycle += base_cycle;
}
}
}
struct state {
int done256count = 0;
map<int, string> available; // 0~255利用可能なスタンプ + 操作列
vvl now_a;
P prev = P(-1, -1);
int stamped_this_turn = -1;
int zobh = 0;
// 「大きいほど小さい」順序
bool operator<(const state& rhs) const {
if (done256count != rhs.done256count)
return done256count > rhs.done256count; // 大きいほうを「より小さい」とみなす
return available.size() > rhs.available.size();
}
};
vector<vector<state>> beam(1001);
unordered_set<int> hash_seen;
void beamsearch() {
for(auto & x : a) for(auto & y : x) y >>= 12;
int beam_width = 100;
{
state start;
start.available[0] = "";
start.now_a = a;
beam[0].push_back(start);
}
int best = 0;
P best_where = P(-1, -1);
rep(i, 1000){
auto [ni, nj] = move_log[i];
rep(is, beam[i].size()){
state &sta = beam[i][is];
state nxt = sta;
if(nxt.stamped_this_turn != -1){
nxt.available.clear();
nxt.available[nxt.stamped_this_turn] = "";
nxt.stamped_this_turn = -1;
}
nxt.prev = P(i, is);
for(auto &x : nxt.available) x.second.push_back(move_cycle[i]);
map<int, string> moved = nxt.available;
for(auto &x : nxt.available){
moved[x.first ^ nxt.now_a[ni][nj]] = x.second + 'C';
}
nxt.available = moved;
if(nxt.now_a[ni][nj] != 255){
int want = 255 ^ nxt.now_a[ni][nj];
if(nxt.available.count(want) && want != 0){
// 更新したやつを入れる
state stamped = nxt;
stamped.done256count++;
stamped.now_a[ni][nj] = 255;
stamped.zobh += ni*10007 + nj;
stamped.zobh %= 1000000007;
if(hash_seen.count(stamped.zobh)) continue;
stamped.stamped_this_turn = want;
stamped.available[want] += 'W';
beam[i+1].push_back(stamped);
}
}
beam[i+1].push_back(nxt);
}
if(beam[i+1].size() == 0){
cerr << "ターン : " << i << endl;
throw runtime_error("ビームが空");
}
sort(beam[i+1].begin(), beam[i+1].end());
while(beam[i+1].size() > beam_width) beam[i+1].pop_back();
// 解の更新
if(beam[i+1][0].done256count > best){
best = beam[i+1][0].done256count;
best_where = P(i+1, 0);
}
}
// best_where から復元
vector<string> res;
while(best_where.first != -1){
auto [i, j] = best_where;
state now = beam[i][j];
if(now.stamped_this_turn != -1){
res.push_back(now.available[now.stamped_this_turn]);
}
best_where = now.prev;
}
reverse(res.begin(), res.end());
int count = 0;
for(auto x : res) {
for(auto y : x) {
cout << y << " ";
count++;
if(count == 1000) break;
}
cout << endl;
if(count == 1000) break;
}
if(count == 1000) cerr << "Force end" << endl;
exit(0);
}
signed main(){
input();
init();
beamsearch();
}