【bzoj2796】 [Poi2012]Fibonacci Representation

给出一个数字,用FIB数列各项加加减减来得到。

问最少要多少个(可以重复使用)

大概试了一下,fibonacci数列的增长是很快的,大概到了90+项就超过了题目范围……

所以每次找一个最近的fibonacci数试一下就好,实测跑得飞快。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 ll f[100],n,m;
 5 inline ll read(){
 6     ll f=1,x=0;char ch;
 7     do{ch=getchar();if(ch==‘-‘)f=-1;}while(ch<‘0‘||ch>‘9‘);
 8     do{x=x*10+ch-‘0‘;ch=getchar();}while(ch>=‘0‘&&ch<=‘9‘);
 9     return f*x;
10 }
11 int work(ll x){
12     if(!x)return x;int i;
13     for(i=1;f[i]<x;i++);
14     return work(min(f[i]-x,x-f[i-1]))+1;
15 }
16 int main(){
17     f[0]=1;f[1]=1;
18     for(int i=2;i<=91;i++)f[i]=f[i-1]+f[i-2];
19     int T=read();
20     while(T--){
21         n=read();
22         printf("%d\n",work(n));
23     }
24     return 0;
25 }
时间: 2024-08-26 07:05:32

【bzoj2796】 [Poi2012]Fibonacci Representation的相关文章

矩阵十题【六】 poj3070 Fibonacci

题目链接:http://poj.org/problem?id=3070 题目大意:给定n和10000,求第n个Fibonacci数mod 10000 的值,n不超过2^31.结果保留四位数字. 很简单的题,和之前做过的相比简单很多了. 构造最简单的斐波那契数列矩阵. #include<iostream> #include<cstring> #include<stdio.h> using namespace std; const int MAX = 2; struct M

【BZOJ2789】[Poi2012]Letters 树状数组

[BZOJ2789][Poi2012]Letters Description 给出两个长度相同且由大写英文字母组成的字符串A.B,保证A和B中每种字母出现的次数相同. 现在每次可以交换A中相邻两个字符,求最少需要交换多少次可以使得A变成B. Input 第一行一个正整数n (2<=n<=1,000,000),表示字符串的长度. 第二行和第三行各一个长度为n的字符串,并且只包含大写英文字母. Output 一个非负整数,表示最少的交换次数. Sample Input 3 ABC BCA Samp

【BZOJ2795】[Poi2012]A Horrible Poem hash

[BZOJ2795][Poi2012]A Horrible Poem Description 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. Input 第一行一个正整数n (n<=500,000),表示S的长度.第二行n个小写英文字母,表示字符串S.第三行一个正整数q (q<=2,000,000),表示询问个数.下面q行每行两个正整数a,b (1<=a<=b<=n),表示询

【BZOJ2803】[Poi2012]Prefixuffix 结论题

[BZOJ2803][Poi2012]Prefixuffix Description 对于两个串S1.S2,如果能够将S1的一个后缀移动到开头后变成S2,就称S1和S2循环相同.例如串ababba和串abbaab是循环相同的.给出一个长度为n的串S,求满足下面条件的最大的L:1. L<=n/22. S的L前缀和S的L后缀是循环相同的. Input 第一行一个正整数n (n<=1,000,000).第二行n个小写英文字母,表示串S. Output 一个整数,表示最大的L. Sample Inpu

【BZOJ2793】【数学】[Poi2012]Vouchers

Description 考虑正整数集合,现在有n组人依次来取数,假设第i组来了x人,他们每个取的数一定是x的倍数,并且是还剩下的最小的x个. 正整数中有m个数被标成了幸运数,问有哪些人取到了幸运数. Input 第一行一个正整数m (m<=1,000,000),下面m行每行一个正整数x (x<=1,000,000),表示x是一个幸运数. 接下来一行一个正整数n (n<=1,000,000),下面n行每行一个正整数x (x<=1,000,000),表示这一组来了x个人. Output

[BZOJ2796][Poi2012]Fibonacci Representation

由于是斐波那契数列,所以$x_i+x_j<=x_k,i<j<k$ 所以猜测可以贪心选择两边近的数处理. 1 #include<cstdio> 2 #include<algorithm> 3 #define ll long long 4 #define mid (l+r>>1) 5 using namespace std; 6 ll f[505],tot=1; 7 inline ll findl(ll x) 8 { 9 int l=1,r=tot,ans

【POJ】3070 Fibonacci(矩阵乘法)

http://poj.org/problem?id=3070 根据本题算矩阵,用快速幂即可. 裸题 #include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <algorithm> using namespace std; #define rep(i, n) for(int i=0; i<

【最小生成树】【kruscal】hdu4786 Fibonacci Tree

假设这张图能够形成具有k条白边的生成树, 则易证k一定形成一个连续的区间[a,b],中间一定不会断开.要是断开--tm怎么可能. 所以求出a,b就好啦,人家都给你把白边赋成1了,直接跑一下最小生成树,再跑一下最大生成树即可咯. #include<cstdio> #include<algorithm> using namespace std; #define N 100010 struct Edge{ int u,v,w; }edges[N]; bool cmp(const Edge

【HDU】1848 Fibonacci again and again

http://acm.hdu.edu.cn/showproblem.php?pid=1848 题意:同nim,3堆,每次取的为fib数,n<=1000 #include <cstdio> #include <cstring> using namespace std; int f[1005], a[100]; bool b[20]; int main() { a[1]=1; a[2]=2; for(int i=3; i<=15; ++i) a[i]=a[i-1]+a[i-