Frog and Portal

Frog and Portal
HihoCoder - 1873
https://vjudge.net/problem/HihoCoder-1873/origin
小青蛙这道题很有趣,巧妙的构造,因为斐波那契里面有1,所以任何正整数都能拆分成斐波那契数的和,问题就在于怎么去拆成和,队友想的是倒着做

1 1 2 3
200 199 198 197

表示的是在第199个位置到终点的方案数,所以只要在前面传送到这个位置就可以了,在前面的时候,隔着一个放一个传送门就能保证唯一,最后堵死

#include <bits/stdc++.h>
#define inf 2333333333333333
#define N 1000010
#define p(a) putchar(a)
#define For(i,a,b) for(long long i=a;i<=b;++i)
//by war
//2020.9.22
using namespace std;
long long m,n,cnt;
long long f[300],ans[N];
void in(long long &x){
    long long y=1;char c=getchar();x=0;
    while(c<'0'||c>'9'){if(c=='-')y=-1;c=getchar();}
    while(c<='9'&&c>='0'){ x=(x<<1)+(x<<3)+c-'0';c=getchar();}
    x*=y;
}
void o(long long x){
    if(x<0){p('-');x=-x;}
    if(x>9)o(x/10);
    p(x%10+'0');
}

signed main(){
    f[200]=1;f[199]=1;
    for(long long i=198;i;i--){
        f[i]=f[i+1]+f[i+2];
        if(f[i]>((long long)1<<34)) break;
        n=i;
    }
    // For(i,n,200){
    //     o(f[i]);p('\n');
    // }
    while(cin>>m){
        if(m==0){
            puts("2");
            puts("1 1");
            puts("2 1");
            continue;
        }
        if(m==1){
            puts("2");
            puts("1 199");
            puts("2 2");
            continue;
        }
        cnt=0;
        For(i,n,200){
            while(f[i]<=m){
                m-=f[i];
                ans[++cnt]=i;
            }
        }
        o(cnt+1);p('\n');
        For(i,1,cnt){
            o(i*2-1);p(' ');o(ans[i]);p('\n');
        }
        o(cnt*2);p(' ');o(cnt*2);p('\n');
    }
    return 0;
}

 

posted @ 2020-09-23 20:03  WeiAR  阅读(133)  评论(0编辑  收藏  举报