Tokio Marine & Nichido Fire Insurance Programming Contest 2021 (AtCoder Regular Contest 122)
阿新 • • 發佈:2021-06-17
\(\sf C-Calculator\)
題目
解法
手玩就能發現,這其實就是將 \(n\) 拆分成幾個斐波那契數。
可以證明,任意正整數 \(n\) 可以被拆分成互異的斐波那契數。又因為如果選擇了 \(\text{fib}_i,\text{fib}_{i+1}\) 肯定就會換成 \(\text{fib}_{i+2}\),所以我們不會選擇連續的斐波那契數。而資料範圍中斐波那契數最多到 \(87\) 項(\(\text{fib}_1=\text{fib}_{2}=1\)),所以如果我們都選奇數項就有 \(44\) 項。不過事實上這個上界達不到,因為 \(\text{fib}_{87}+\text{fib}_{85}+\text{fib}_{83}>10^{18}\)
構造就是邊加入 \(1\),邊用 \(3,4\) 操作拓展斐波那契數列,\(3,4\) 操作的上界是 \(86\)。
所以總體上界為 \(130\),足以通過此題。
程式碼
#include <bits/stdc++.h> using namespace std; #define rep(i,_l,_r) for(register signed i=(_l),_end=(_r);i<=_end;++i) #define fep(i,_l,_r) for(signed i=(_l),_end=(_r);i>=_end;--i) #define erep(i,u) for(signed i=head[u],v=to[i];i;i=nxt[i],v=to[i]) #define efep(i,u) for(signed i=Head[u],v=to[i];i;i=nxt[i],v=to[i]) #define print(x,y) write(x),putchar(y) #define debug(...) do {cerr<<__LINE__<<" : ("#__VA_ARGS__<<") = "; Out(__VA_ARGS__); cerr<<flush;} while(0) template <typename T> void Out(T x) {cerr<<x<<"\n";} template <typename T,typename ...I> void Out(T x,I ...NEXT) {cerr<<x<<", "; Out(NEXT...);} template <class T> inline T read(const T sample) { T x=0; int f=1; char s; while((s=getchar())>'9'||s<'0') if(s=='-') f=-1; while(s>='0'&&s<='9') x=(x<<1)+(x<<3)+(s^48),s=getchar(); return x*f; } template <class T> inline void write(const T x) { if(x<0) return (void) (putchar('-'),write(-x)); if(x>9) write(x/10); putchar(x%10^48); } template <class T> inline T Max(const T x,const T y) {if(x>y) return x; return y;} template <class T> inline T Min(const T x,const T y) {if(x<y) return x; return y;} template <class T> inline T fab(const T x) {return x>0?x:-x;} template <class T> inline T gcd(const T x,const T y) {return y?gcd(y,x%y):x;} template <class T> inline T lcm(const T x,const T y) {return x/gcd(x,y)*y;} typedef long long ll; ll n,f[100]; int sta[100],tp,ans[200],len,fuck; void init() { f[1]=f[2]=1; rep(i,3,90) f[i]=f[i-1]+f[i-2]; } int main() { init(); n=read(9ll); fep(i,90,1) if(n>=f[i]) sta[++tp]=i,n-=f[i]; fep(i,tp,1) if(sta[i]&1) { while(fuck<sta[i]-1) { if(fuck&1) ans[++len]=4; else ans[++len]=3; ++fuck; } ans[++len]=1; } else { while(fuck<sta[i]-1) { if(fuck&1) ans[++len]=4; else ans[++len]=3; ++fuck; } ans[++len]=2; } print(len,'\n'); fep(i,len,1) print(ans[i],'\n'); return 0; }