yukicoder No.320 眠れない夜に

今年最後の問題かなぁ…(冬休みの課題の息抜きに)

問題

No.320 眠れない夜に - yukicoder

解法

まず、早めに間違えると大きな誤差を生むことが分かる。その様子を見てみる。例えばa3で間違えると、
a3=1(-1)、a4=2(-1)、a5=3(-2)、a6=5(-3)、…
と、元の値からどの位離れていくかがフィボナッチ数列になる。

よって、予めフィボナッチ数列の80項まで調べておき(ギリギリC++のlong longで収まる。不安だったのでJavaでBigInteger使って確かめた。)、どの位足りないかを見るためm=an-mとする。
a3に間違えた時から順に仮定していき、変化量がm以下ならmから引いてあげる。実際はフィボナッチ数列のa(n-2)から値を下げるようループを回してあげる。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll fib[100];
bool use[100];
int main(){
    fib[0]=fib[1]=1;
    for(int i=2;i<80;i++)   fib[i]=fib[i-1]+fib[i-2];
    ll n,m; cin>>n>>m;  m=fib[n-1]-m;
    int ans=0;
    for(int i=n-3;i>=0;i--){
        if(not(use[i]) and m>=fib[i]){
            m-=fib[i];
            ans++;
            use[i]=true;
        }
    }
    if(m==0) cout<<ans<<endl;
    else  cout<<-1<<endl;
    return 0;
}

感想

いや、普通にJava使えば良かったのでは…Javaの練習問題にも丁度いい気がする。
来年はPythonJavaをさっさと使えるようにしましょう。