結果
問題 |
No.5022 XOR Printer
|
ユーザー |
|
提出日時 | 2025-07-26 15:16:27 |
言語 | C++23 (gcc 13.3.0 + boost 1.87.0) |
結果 |
AC
|
実行時間 | 1,984 ms / 2,000 ms |
コード長 | 6,754 bytes |
コンパイル時間 | 3,289 ms |
コンパイル使用メモリ | 303,004 KB |
実行使用メモリ | 7,716 KB |
スコア | 4,790,449,772 |
最終ジャッジ日時 | 2025-07-26 15:18:15 |
合計ジャッジ時間 | 106,686 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 50 |
ソースコード
#include <bits/stdc++.h> using namespace std; struct Timer { using Clock = chrono::high_resolution_clock; chrono::time_point<Clock> st{Clock::now()}; double elapsed() const { return chrono::duration<double>(Clock::now() - st).count(); } }; constexpr int N = 10; constexpr int T = 1000; constexpr int choose = 6; constexpr int seed = 123456789; constexpr double TL = 1.98; tuple<int64_t, string, vector<vector<uint32_t>>> run(const vector<char>& out, vector<vector<uint32_t>>& board) { size_t x = 0, y = 0; uint32_t s = 0; size_t step = 0; for (char op : out) { switch (op) { case 'U': if (x == 0) { return {0, "Move out of board at step " + to_string(step), board}; } --x; break; case 'D': if (x + 1 >= static_cast<size_t>(N)) { return {0, "Move out of board at step " + to_string(step), board}; } ++x; break; case 'L': if (y == 0) { return {0, "Move out of board at step " + to_string(step), board}; } --y; break; case 'R': if (y + 1 >= static_cast<size_t>(N)) { return {0, "Move out of board at step " + to_string(step), board}; } ++y; break; case 'W': board[x][y] ^= s; break; case 'C': s ^= board[x][y]; break; default: return {0, "Invalid operation", board}; } ++step; } uint64_t sum = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { sum += board[i][j]; } } return {static_cast<int64_t>(sum), "", board}; } int main() { int n_in, t_in; if (!(cin >> n_in >> t_in)) return 0; vector<vector<uint32_t>> A(N, vector<uint32_t>(N, 0)); for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { cin >> A[i][j]; } } Timer timer; mt19937 rng(seed); uniform_int_distribution<int> dist(0, N*N - 1); int best_score = -1; int iter = 0; vector<int> best_combination, best_candidate_vals; while (timer.elapsed() < TL) { vector<int> combination, candidate_vals; while (combination.size() < choose) { int idx = dist(rng); if (find(combination.begin(), combination.end(), idx) == combination.end()) { combination.emplace_back(idx); } } candidate_vals.emplace_back(0); for (int i = 0; i < choose; ++i) { candidate_vals.emplace_back(A[combination[i] / N][combination[i] % N] ^ candidate_vals.back()); } int score = 0; for (int i = 0; i < N; i++) { for (int j = 0; j < N; j++) { uint32_t val = 0; for (int v : candidate_vals) { val = max(val, A[i][j] ^ v); } score += val; } } if (score > best_score) { best_score = score; best_combination = combination; best_candidate_vals = candidate_vals; } iter++; } // for (int idx : best_combination) { // cerr << idx << ' ' << A[idx / N][idx % N] << endl; // } // cerr << "Best score: " << best_score << endl; // cerr << "Iterations: " << iter << endl; vector<vector<int>> result(N, vector(N, -1)); for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { if (find(best_combination.begin(), best_combination.end(), i * N + j) != best_combination.end()) { continue; } int val = -1; int idx = -1; for (int k = 0; k < choose + 1; ++k) { int candidate_val = A[i][j] ^ best_candidate_vals[k]; if (candidate_val > val) { val = candidate_val; idx = k; } } result[i][j] = idx; } } int score = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { if (result[i][j] == -1) { score += A[i][j]; } else { score += A[i][j] ^ best_candidate_vals[result[i][j]]; } } } cerr << "Final score: " << score << endl; vector<char> output; output.reserve(1000); vector A_ = A; int s = 0; int curr_x = 0, curr_y = 0; // 現在位置を追跡 for (int i = 0; i < choose + 1; ++i) { assert(s == best_candidate_vals[i]); // cerr << "s: " << s << endl; // cerr << "predicted: " << best_candidate_vals[i] << endl; for (int j = 0; j < N; ++j) { for (int k = 0; k < N; ++k) { int y = (j % 2 == 0) ? k : N - 1 - k; // jが偶数ならk, 奇数ならN-1-k if (result[j][y] == i) { output.emplace_back('W'); A_[j][y] ^= s; } if (k != N-1) { output.emplace_back(j % 2 ? 'L' : 'R'); curr_y += (j % 2 ? -1 : 1); } } if (j != N-1) { output.emplace_back('D'); curr_x++; } } if (i == choose) break; // 目標位置への移動 int target_x = best_combination[i] / N; int target_y = best_combination[i] % N; // X方向の移動 while (curr_x > target_x) { output.emplace_back('U'); curr_x--; } // Y方向の移動 while (curr_y < target_y) { output.emplace_back('R'); curr_y++; } output.emplace_back('C'); s ^= A_[target_x][target_y]; while (curr_y > 0) { output.emplace_back('L'); curr_y--; } while (curr_x > 0) { output.emplace_back('U'); curr_x--; } } int res_score = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { res_score += A_[i][j]; cerr << A_[i][j] << ' '; } cerr << endl; } cerr << "Result score: " << res_score << endl; auto res = run(output, A); for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { cerr << get<2>(res)[i][j] << ' '; } cerr << endl; } cerr << "Run result: " << get<0>(res) << ", " << get<1>(res) << endl; for (char c : output) { cout << c << endl; } }