ARC122C-Calculator【乱搞,构造】
生活随笔
收集整理的這篇文章主要介紹了
ARC122C-Calculator【乱搞,构造】
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
正題
題目鏈接:https://atcoder.jp/contests/arc122/tasks/arc122_c
題目大意
一個數(shù)對開始是(0,0)(0,0)(0,0),每次可以選擇一個數(shù)加一或者讓一個數(shù)加上另一個數(shù),求使得第一個數(shù)變成nnn的方案。步數(shù)不超過130130130。
1≤n≤10181\leq n\leq 10^{18}1≤n≤1018
解題思路
官方是斐波那契,但是我考試的時候過法比較神奇。
看上去比較像更相減損,但是不知道第二個數(shù)是多少,感覺我們應(yīng)該能找到一個數(shù)對(n,k)(n,k)(n,k)使得它更相減損的步驟很少。
考慮的分散一點,設(shè)n=xk+kn=xk+kn=xk+k。那么我們相當(dāng)于要找到一個xxx使得xk+kk=1x\frac{xk+k}{k}=\frac{1}{x}kxk+k?=x1?。
然后解出來得到x=5?12x=\frac{\sqrt 5-1}{2}x=25??1?(其實就是黃金分割率)。
所以我們讓k=n×5?12k=n\times \frac{\sqrt 5-1}{2}k=n×25??1?然后更相減損下去,之后會發(fā)現(xiàn)有點誤差,我們前后各枚舉100001000010000找到一個滿足條件的就好了。
code
#include<cstdio> #include<cstring> #include<algorithm> #include<vector> #include<cmath> #define ll long long using namespace std; ll n;vector<ll> z; void print(ll x,ll y){if(!x){while(y&&z.size()<=130)y--,z.push_back(2);return;}if(!y){while(x&&z.size()<=130)x--,z.push_back(1);return;}if(x<y) print(x,y-x),z.push_back(4);else print(x-y,y),z.push_back(3); } signed main() {scanf("%lld",&n);double M=(sqrt(5.0)-1.0)*(double)n/2.0;ll m=M;for(ll i=max(m-10000,0ll);i<=m+10000;i++){print(n,i);if(z.size()>130){z.clear();continue;}printf("%lld\n",z.size());for(ll i=0;i<z.size();i++)printf("%lld\n",z[i]);break;}return 0; }總結(jié)
以上是生活随笔為你收集整理的ARC122C-Calculator【乱搞,构造】的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 3500左右电脑配置清单(3500左右电
- 下一篇: AT2390-[AGC016F]Game