結果
問題 |
No.5022 XOR Printer
|
ユーザー |
![]() |
提出日時 | 2025-07-26 15:53:56 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,767 ms / 2,000 ms |
コード長 | 8,879 bytes |
コンパイル時間 | 4,678 ms |
コンパイル使用メモリ | 265,900 KB |
実行使用メモリ | 7,716 KB |
スコア | 5,203,445,555 |
最終ジャッジ日時 | 2025-07-26 15:55:25 |
合計ジャッジ時間 | 87,808 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge6 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 50 |
ソースコード
#include <bits/stdc++.h> #include <atcoder/all> using namespace std; using namespace atcoder; using ll = long long; constexpr ll mod = 1e9 + 7; constexpr ll INF = (1LL << 62) - (1LL << 31) - 1; #define REP(i, init, n) for(int i = (int)(init); i < (int)(n); i++) #define RREP(i, init, n) for(int i = (int)(init); i >= (int)(n); i--) #define All(A) A.begin(), A.end() #define rAll(A) A.rbegin(), A.rend() #define vi vector<int> #define vl vector<long> #define vvi vector<vector<int>> #define vvl vector<vector<long>> #define pint pair<int, int> #define plong pair<long, long> int N, T; vvi A; namespace Annealing { bool is_online_judge() { return true; } class TimeKeeper { public: std::chrono::high_resolution_clock::time_point m_start_time; int64_t m_time_threshold; int64_t dev_env_threshold; int dev_const = 1; TimeKeeper(): m_start_time(std::chrono::high_resolution_clock::now()) { if(!is_online_judge()) { dev_const = 1; } } void set_time_threshold(const int64_t &time_threshold) { m_time_threshold = time_threshold; dev_env_threshold = time_threshold * dev_const; } bool is_time_over() { using std::chrono::duration_cast; using std::chrono::milliseconds; auto diff = std::chrono::high_resolution_clock::now() - (this->m_start_time); return duration_cast<milliseconds>(diff).count() >= time_threshold(); } int cur_time() { using std::chrono::duration_cast; using std::chrono::milliseconds; auto diff = std::chrono::high_resolution_clock::now() - (this->m_start_time); return duration_cast<milliseconds>(diff).count(); } long double elapsed_ratio() { return (long double)(this -> cur_time()) / time_threshold(); } int64_t time_threshold() { if(!is_online_judge()) { return dev_env_threshold; } return m_time_threshold; } }; class Temperature { private: long double m_initial_temperature; long double m_last_temperature; int init_elapsed; TimeKeeper tk; public: Temperature(const long double &initial_temperature, const long double &last_temperature, const TimeKeeper &tk): m_initial_temperature(initial_temperature), m_last_temperature(last_temperature), tk(tk) { init_elapsed = this->tk.cur_time(); } long double get_temperature() { long double ratio = (long double)(tk.cur_time() - init_elapsed) / (tk.time_threshold() - init_elapsed); return m_initial_temperature + (m_last_temperature - m_initial_temperature) * ratio; } long double prob(const long double &delta) { return exp(-delta / get_temperature()); } bool changed(const long double &delta) { return (delta <= 0) || (rand() < prob(delta) * RAND_MAX); } }; } int calc_dist(const pint &a, const pint &b) { return abs(a.first - b.first) + abs(a.second - b.second); } int calc_score(pint &cur, vector<pint> &targets, vvi &shelter_map) { pint last = targets.back(); if(shelter_map[last.first][last.second] == 1) { return 1 << 30; } int score = calc_dist(cur, targets[0]); REP(i, 0, targets.size() - 1) { score += calc_dist(targets[i], targets[i + 1]); } return score; } void move_U(pint &cur, string &ans) { cur.first--; ans += 'U'; } void move_D(pint &cur, string &ans) { cur.first++; ans += 'D'; } void move_L(pint &cur, string &ans) { cur.second--; ans += 'L'; } void move_R(pint &cur, string &ans) { cur.second++; ans += 'R'; } void write(int &s, pint &cur, string &ans) { A[cur.first][cur.second] ^= s; ans += 'W'; } void copy(int &s, pint &cur, string &ans) { s ^= A[cur.first][cur.second]; ans += 'C'; } void move(pint &cur, const pint &next, string &ans) { while(cur != next) { if(cur.first < next.first) { move_D(cur, ans); } else if(cur.first > next.first) { move_U(cur, ans); } else if(cur.second < next.second) { move_R(cur, ans); } else if(cur.second > next.second) { move_L(cur, ans); } } } void solve() { pint cur = {0, 0}; int s = 0; int move_count = 0; string ans = ""; vector<pint> shelters; vvi shelters_map(N, vi(N, 0)); Annealing::TimeKeeper tk; mt19937 mt(chrono::steady_clock::now().time_since_epoch().count()); RREP(b, 19, 10) { int mask = (1 << b); int min_dist = 100; pint next_target = {-1, -1}; // cerr << "cur: " << cur.first << " " << cur.second << " s: " << s << " mask: " << bitset<20>(mask) << endl; REP(i, 0, N) { REP(j, 0, N) { if(shelters_map[i][j] == 1) continue; if(s & mask) { if((A[i][j] & mask) == 0) { int dist = calc_dist(cur, {i, j}); if(dist < min_dist) { min_dist = dist; next_target = {i, j}; } } } else { if(A[i][j] & mask) { int dist = calc_dist(cur, {i, j}); if(dist < min_dist) { min_dist = dist; next_target = {i, j}; } } } } } // cerr << "next_target: " << next_target.first << " " << next_target.second << endl; if(next_target.first == -1) { break; } move(cur, next_target, ans); copy(s, cur, ans); if(ans.size() >= T) break; cerr << b << " " << cur.first << " " << cur.second << " " << s << endl; cerr << bitset<20>(s) << endl; vvi board(N, vi(N, 0)); int rest = 0; vector<pint> targets; REP(i, 0, N) { REP(j, 0, N) { if(A[i][j] & mask) { board[i][j] = 1; } else { targets.push_back({i, j}); rest++; } } } tk.set_time_threshold(196 * (20 - b)); Annealing::Temperature temp(10, 0, tk); int best_score = calc_score(cur, targets, shelters_map); int cur_score = best_score; int itr = 0, update_cnt = 0; while(!tk.is_time_over()) { int a = mt() % targets.size(); int b = mt() % targets.size(); if(a == b) continue; itr++; swap(targets[a], targets[b]); int new_score = calc_score(cur, targets, shelters_map); if(temp.changed(new_score - cur_score)) { update_cnt++; cur_score = new_score; if(new_score < best_score) { best_score = new_score; } } else { swap(targets[a], targets[b]); } } cerr << "itr: " << itr << " update_cnt: " << update_cnt << " best_score: " << best_score << endl; REP(i, 0, targets.size()) { pint target = targets[i]; move(cur, target, ans); if(ans.size() >= T) break; if(i == targets.size() - 1 && b < 19) { shelters.push_back(cur); shelters_map[cur.first][cur.second] = 1; copy(s, cur, ans); break; } write(s, cur, ans); board[target.first][target.second] = 1; rest--; } if(ans.size() >= T) break; /* REP(i, 0, N) { REP(j, 0, N) { cerr << bitset<20>(A[i][j]) << " "; } cerr << endl; } */ } long final_score = 0; REP(i, 0, N) { REP(j, 0, N) { final_score += A[i][j]; } } cerr << "final score: " << final_score << endl; if(ans.size() >= T) { ans = ans.substr(0, T); } for(char c: ans) { cout << c << endl; } } int main() { cin.tie(nullptr); ios::sync_with_stdio(false); cin >> N >> T; A.resize(N, vi(N)); REP(i, 0, N) { REP(j, 0, N) { cin >> A[i][j]; } } solve(); }