ARC122 C - Calculator(构造)

目录

Description

将 x 变为 n,有一下四种操作,操作次数不能超过 130

1. x = x + 1
2. y = y + 1
3. x = x +y
4. y = x +y

State

\(1<=n<=10^{18}\)

Input

4

Output

5
1
4
2
3
1

Solution

题目看出考点为斐波那契数才可以继续往下做,先打一个表

\[row = 1\qquad 1 \quad 1\\ row = 2\qquad 2 \quad 3 \\ row = 3\qquad 5 \quad 8 \\ row = 4\qquad 13 \quad 21 \\ row = 5\qquad 34 \quad 55 \\ row = 6\qquad 89 \quad 144 \\ row = 7\qquad 233 \quad 377 \\ \]

接下来手算一下 \(385(377+8)\)\(382(377+5)\) ,发现想要在 \(377\) 加上这两个数,需要在 \(34\)\(55\)\(+1\) 就可以,而 \(5\)\(8\) 的下标分别是 \(5\)\(6\),也就是说,\(14(f[14]=377) - 5 + 1 = 10(f[10]=55),\quad 14 - 6 + 1 = 9(f[9] = 34)\)

剩下的就是代码细节的处理了

Code

const int N = 2e5 + 5;

    ll n, m, _;
    int i, j, k;
    ll a[N];

void init()
{
    a[1] = 1, a[2] = 1;
    for(i = 3; i <= 88; i++){
        a[i] = a[i - 1] + a[i - 2];
    }
}

signed main()
{
    //IOS;
    init();
    while(~ sll(n)){
        int len = 0, f[90] = {0};
        for(int i = 87; i; i--){
            if(n >= a[i]){
                if(!len) len = i;
                n -= a[i];
                f[len - i + 1] = 1;
            }
        }
        int tag = len % 2;
        vector<int> ans;
        rep(i, 1, len){
            if(f[i]){
                if(tag == 0) ans.pb(2);
                else ans.pb(1);
            }
            if(tag == 0) ans.pb(3);
            else ans.pb(4);
            tag ^= 1;
        }
        pd(ans.size());
        for(auto it : ans) pd(it);
    }
    return 0;
}
posted @ 2021-08-04 10:12  Bcoi  阅读(50)  评论(0)    收藏  举报