結果
| 問題 | No.5022 XOR Printer |
| コンテスト | |
| ユーザー |
sig_256
|
| 提出日時 | 2025-07-26 16:57:53 |
| 言語 | C++17(gcc12) (gcc 12.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 897 ms / 2,000 ms |
| コード長 | 6,501 bytes |
| コンパイル時間 | 2,897 ms |
| コンパイル使用メモリ | 98,844 KB |
| 実行使用メモリ | 7,720 KB |
| スコア | 4,799,911,557 |
| 最終ジャッジ日時 | 2025-07-26 17:01:11 |
| 合計ジャッジ時間 | 38,997 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
| 純コード判定しない問題か言語 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| other | AC * 50 |
ソースコード
#include <iostream>
#include <utility>
#include <array>
#include <vector>
#include <set>
#ifndef INT_HPP
#define INT_HPP
#include <cstdint>
using u8 = std::uint8_t;
using u16 = std::uint16_t;
using u32 = std::uint32_t;
using u64 = std::uint64_t;
#define U8MAX UINT8_MAX // 255
#define U16MAX UINT16_MAX // 65535
#define U32MAX UINT32_MAX // 4294967295 > 4.29*10⁹
#define U64MAX UINT64_MAX // 18446744073709551615 > 1.84*10¹⁹
using i8 = std::int8_t;
using i16 = std::int16_t;
using i32 = std::int32_t;
using i64 = std::int64_t;
#define I8MIN INT8_MIN // -128
#define I16MIN INT16_MIN // -32768
#define I32MIN INT32_MIN // -2147483648 < -2.14*10⁹
#define I64MIN INT64_MIN // -9223372036854775808 < -9.22*10¹⁸
#define I8MAX INT8_MAX // 127
#define I16MAX INT16_MAX // 32767
#define I32MAX INT32_MAX // 2147483647 > 2.14*10⁹
#define I64MAX INT64_MAX // 9223372036854775807 > 9.22*10¹⁸
#ifdef __SIZEOF_INT128__
using u128 = __uint128_t;
using i128 = __int128_t;
#define U128MAX u128(u128(0) - 1) // 340282366920938463463374607431768211455 > 3.40*10³⁸
#define I128MAX i128(U128MAX >> 1) // 170141183460469231731687303715884105727 > 1.70*10³⁸
#define I128MIN i128(-I128MAX - 1) // -170141183460469231731687303715884105728 < -1.70*10³⁸
#endif
#include <cstddef>
using std::size_t;
using std::byte;
#endif
#ifndef FLOAT_HPP
#define FLOAT_HPP
#include <cfloat>
using f32 = float;
using f64 = double;
using f128 = long double;
#endif
const u8 N = 10;
const u16 T = 1000;
class YX {
public:
u8 y = 0, x = 0;
YX() {}
YX(u8 _y, u8 _x) : y(_y), x(_x) {}
u8 dist(const YX & other) const{
u8 res = 0;
if(y > other.y) res += y - other.y;
else res += other.y - y;
if(x > other.x) res += x - other.x;
else res += other.x - x;
return res;
}
bool operator<(const YX & other) const{
if(x != other.x) return x < other.x;
else return y < other.y;
}
};
using Target = std::pair<YX, u32>;
struct Targetcomp{
bool operator()(const Target & a, const Target & b) const{
return a.first < b.first;
}
};
using TargetsSet = std::set<Target, Targetcomp>;
class Num {
u32 val;
public:
u32 get() const{
return val;
}
void set(const u32 a){
val = a;
}
void w(const u32 s){
val ^= s;
}
u32 score(const u32 s) const{
u32 nval = val ^ s;
if(nval < val) return 0;
else return nval - val;
}
};
std::array<std::array<Num, N>, N> A_base, A;
namespace ANS {
std::string ans;
void moveto(YX from, YX to){
while(from.x > to.x) ans.push_back('L'), from.x --;
while(from.x < to.x) ans.push_back('R'), from.x ++;
while(from.y > to.y) ans.push_back('U'), from.y --;
while(from.y < to.y) ans.push_back('D'), from.y ++;
}
void write(){
ans.push_back('W');
}
void get(){
ans.push_back('C');
}
}
namespace IO {
void in(){
u16 _N, _T;
std::cin >> _N >> _T;
for(u8 y = 0; y < N; ++y){
for(u8 x = 0; x < N; ++x){
u32 a;
std::cin >> a;
A_base[y][x].set(a);
A[y][x].set(a);
}
}
}
void out(){
u16 len = T;
if(ANS::ans.size() < len) len = ANS::ans.size();
for(u16 t = 0; t < len; ++t){
std::cout << ANS::ans[t] << '\n';
}
std::cout << std::flush;
}
}
inline TargetsSet::const_iterator execute_nearest(const TargetsSet & targets, const YX & from){
TargetsSet::const_iterator res = targets.begin();
f64 max_efficiency = 0, efficiency;
for(auto it = targets.begin(); it != targets.end(); ++it){
efficiency = it->second / (from.dist(it->first) + 1);
if(efficiency > max_efficiency){
max_efficiency = efficiency;
res = it;
}
}
return res;
}
f64 execute(bool simulate, YX & from, u32 s, u16 offset){
TargetsSet targets;
for(u8 y = 0; y < N; ++y){
if(ANS::ans.size() < 900 &&(y == 4 || y == 5)) continue;
for(u8 x = 0; x < N; ++x){
targets.emplace(YX{y, x}, A[y][x].score(s));
}
}
f64 max_efficiency = 0, efficiency;
u32 total = 0;
while(true){
if(targets.empty()) break;
auto nearest = execute_nearest(targets, from);
u8 dist = from.dist(nearest->first);
total += nearest->second;
offset += dist + 1;
efficiency = total / offset;
if(max_efficiency > efficiency) break;
max_efficiency = efficiency;
if(!simulate){
ANS::moveto(from, nearest->first);
ANS::write();
A[nearest->first.y][nearest->first.x].w(s);
}
from = nearest->first;
targets.erase(nearest);
}
return max_efficiency;
}
u16 s_update(const std::vector<YX> & src, YX & from, u32 & s, u32 least){
f64 max_efficiency = 0;
u16 best_b = U16MAX;
for(u16 b = 1; b < (1 << src.size()); ++b){
u8 last = 0;
u32 s_temp = s;
for(u8 i = 0; i < src.size(); ++i){
if(b & (1 << i)){
s_temp ^= A[src[i].y][src[i].x].get();
last = i;
}
}
if(ANS::ans.size() == 296) std::clog << s_temp << ' ';
if((least ^ s_temp) < least) continue;
YX srcend = src[last];
f64 efficiency = execute(true, srcend, s_temp, 1 + last);
if(efficiency > max_efficiency){
max_efficiency = efficiency;
best_b = b;
}
}
if(best_b == U16MAX) return 0;
u8 offset = 0;
for(u8 i = 0; i < src.size(); ++i){
if(best_b & (1 << i)){
offset += from.dist(src[i]) + 1;
ANS::moveto(from, src[i]);
from = src[i];
s ^= A[src[i].y][src[i].x].get();
ANS::get();
}
}
std::clog << s << ' ';
return offset;
}
std::vector<YX> route(YX from){
std::vector<YX> res;
if(from.y < 5){
for(u8 i = 0; i < 5; ++i){
if(from.y == 4) break;
if(from.y > 1)
res.emplace_back(from.y, from.x);
from.y ++;
}
}
else{
for(u8 i = 0; i < 5; ++i){
if(from.y == 5) break;
if(from.y < 8)
res.emplace_back(from.y, from.x);
from.y --;
}
}
u8 dx = (5 - res.size()) * 2 + 1;
if(from.x < 5){
while(--dx && from.x + 2 < N){
from.x ++;
res.emplace_back(from.y, from.x);
}
from.x ++;
}
else{
while(--dx && from.x > 1){
from.x --;
res.emplace_back(from.y, from.x);
}
from.x --;
}
if(from.y == 4){
while(res.size() < 10 && from.y > 0){
from.y --;
res.emplace_back(from.y, from.x);
}
}
else{
while(res.size() < 10 && from.y + 1 < N){
from.y ++;
res.emplace_back(from.y, from.x);
}
}
return res;
}
u32 A_min(){
u32 res = 1048576;
for(u8 y = 0; y < N; ++y){
for(u8 x = 0; x < N; ++x){
if(A[y][x].get() < res){
res = A[y][x].get();
}
}
}
return res;
}
int main(){
IO::in();
ANS::ans.reserve(T);
u32 s = 0;
YX me(0, 0);
while(ANS::ans.size() < T){
u16 offset = s_update(route(me), me, s, A_min());
if(offset == 0) break;
execute(false, me, s, offset);
}
IO::out();
return 0;
}
sig_256