結果
| 問題 |
No.3162 Five Two Three
|
| コンテスト | |
| ユーザー |
|
| 提出日時 | 2025-05-05 02:16:19 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
WA
|
| 実行時間 | - |
| コード長 | 4,513 bytes |
| コンパイル時間 | 2,434 ms |
| コンパイル使用メモリ | 212,400 KB |
| 実行使用メモリ | 7,848 KB |
| 最終ジャッジ日時 | 2025-05-05 02:16:30 |
| 合計ジャッジ時間 | 9,576 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 2 WA * 1 |
| other | AC * 62 WA * 125 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
using i128 = __int128_t;
const int64 LIM = 1'000'000'000'000LL;
const int MAX_DEPTH = 35; // 単純 BFS で現実的に耐えられる限界付近
/* キー圧縮 ───────────── */
static inline i128 pack(int64 a, int64 b){ return (i128(a)<<64) | (uint64_t)b; }
/* 探索ノード ─────────── */
struct Node{
int64 pre, cur;
i128 par; // 親のキー(root は -1)
uint8_t depth; // root からの深さ
bool hasZ; // ここまでに Z を見たか
};
/* 片側フロンティアを 1 層広げる */
void expand_layer(queue<i128>& q,
unordered_map<i128,Node>& mp,
int64 Z)
{
size_t layer_sz = q.size();
while(layer_sz--){
i128 k = q.front(); q.pop();
Node nd = mp[k];
int64 a = nd.pre, b = nd.cur;
int64 nxt[2] = {a + b, llabs(a - b)};
for(int t=0;t<2;++t){
int64 c = nxt[t];
if(c<0 || c>LIM) continue;
i128 nk = pack(b,c);
if(mp.count(nk)) continue;
mp.emplace(nk, Node{b,c,k, uint8_t(nd.depth+1),
nd.hasZ || (c==Z)});
q.push(nk);
}
}
}
/* 復元して出力 */
void output_path(i128 meetL, i128 meetR,
const unordered_map<i128,Node>& L,
const unordered_map<i128,Node>& R)
{
vector<int64> left, right;
/* 左列:cur を取りながら root へ */
for(i128 k=meetL; k!=-1; k=L.at(k).par)
left.push_back(L.at(k).cur);
reverse(left.begin(), left.end());
/* 右列:cur を取りながら root へ。ただし重複する q を除く */
bool first = true;
for(i128 k=meetR; k!=-1; k=R.at(k).par){
if(first){ // (q,r) の r だけ
right.push_back(R.at(k).cur);
first=false;
}else{ // 以降は pre を採用
right.push_back(R.at(k).pre);
}
}
/* 結合して表示 */
left.insert(left.end(), right.begin(), right.end());
cout<<left.size()<<"\n";
for(size_t i=0;i<left.size();++i)
cout<<left[i]<<(i+1==left.size()?'\n':' ');
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int64 X,Y,Z;
if(!(cin>>X>>Y>>Z)) return 0;
/* 長さ3で終了? */
if(llabs(X-Y)==Z){
cout<<3<<"\n"<<X<<" "<<Z<<" "<<Y<<"\n";
return 0;
}
/* 両端が 0,0,1 などの超簡単ケースはスキップ
(BFS でも瞬時に解けるので敢えて条件分岐しない) */
/* 初期化 ------------------------------------------------------- */
unordered_map<i128,Node> L, R;
queue<i128> qL, qR;
int64 dL = (X==0?1:0);
int64 dR = (Y==0?1:0);
i128 kL = pack(dL,X);
i128 kR = pack(Y,dR);
L.emplace(kL, Node{dL,X,-1,0,(dL==Z)||(X==Z)});
R.emplace(kR, Node{Y,dR,-1,0,(Y==Z)||(dR==Z)});
qL.push(kL);
qR.push(kR);
/* 双方向 BFS ---------------------------------------------------- */
for(int depth=1; depth<=MAX_DEPTH; ++depth){
/* 小さい方のフロンティアを拡張 */
if(qL.size() <= qR.size()){
expand_layer(qL,L,Z);
}else{
expand_layer(qR,R,Z);
}
/* 衝突検査:小さい map から大きい map へ */
const auto &S = (L.size() < R.size()) ? L : R;
const auto &T = (L.size() < R.size()) ? R : L;
for(const auto &kv : S){
const Node &nd = kv.second; // (p,q)
int64 p = nd.pre, q = nd.cur;
/* r は p±q の 2 通りだけ */
int64 cand[2] = { llabs(p-q), p+q };
for(int t=0;t<2;++t){
int64 r = cand[t];
if(r<0 || r>LIM) continue;
auto it = T.find(pack(q,r));
if(it==T.end()) continue;
const Node &nd2 = it->second; // (q,r)
if(!(nd.hasZ || nd2.hasZ || q==Z || r==Z)) continue;
/* 左右どちらが S/T かで meetL/meetR を決める */
i128 meetL, meetR;
if(&S==&L){ meetL = kv.first; meetR = it->first; }
else { meetL = it->first; meetR = kv.first; }
output_path(meetL, meetR, L, R);
return 0;
}
}
}
cout<<-1<<"\n";
return 0;
}