ARC122C-Calculator【乱搞,构造】
正題
題目鏈接:https://atcoder.jp/contests/arc122/tasks/arc122_c
題目大意
一個(gè)數(shù)對(duì)開始是(0,0)(0,0)(0,0),每次可以選擇一個(gè)數(shù)加一或者讓一個(gè)數(shù)加上另一個(gè)數(shù),求使得第一個(gè)數(shù)變成nnn的方案。步數(shù)不超過(guò)130130130。
1≤n≤10181\leq n\leq 10^{18}1≤n≤1018
解題思路
官方是斐波那契,但是我考試的時(shí)候過(guò)法比較神奇。
看上去比較像更相減損,但是不知道第二個(gè)數(shù)是多少,感覺我們應(yīng)該能找到一個(gè)數(shù)對(duì)(n,k)(n,k)(n,k)使得它更相減損的步驟很少。
考慮的分散一點(diǎn),設(shè)n=xk+kn=xk+kn=xk+k。那么我們相當(dāng)于要找到一個(gè)xxx使得xk+kk=1x\frac{xk+k}{k}=\frac{1}{x}kxk+k?=x1?。
然后解出來(lái)得到x=5?12x=\frac{\sqrt 5-1}{2}x=25??1?(其實(shí)就是黃金分割率)。
所以我們讓k=n×5?12k=n\times \frac{\sqrt 5-1}{2}k=n×25??1?然后更相減損下去,之后會(huì)發(fā)現(xiàn)有點(diǎn)誤差,我們前后各枚舉100001000010000找到一個(gè)滿足條件的就好了。
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【乱搞,构造】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 3500左右电脑配置清单(3500左右电
- 下一篇: 直播电脑最低配置要求(直播电脑最低配置)