UVALive 3357 Pinary

UVALive 3357 Pinary

(斐波那契数列,递推)

Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu 

Description

``Pinary" number is a positive number using only two digits ``0" and ``1" with usual rule that it must not begin with a 0, and the additional rule that two successive digits must not be both ``1". This means that the factor ``11" is forbidden in the string. So the allowed Pinary writings are 1, 10, 100, 101, 1000, 1001,..., 100010101010100010001 . For example, ``100101000" is a Pinary number, but neither ``0010101" nor ``10110001" are Pinary numbers. 

Each Pinary number represents a positive integer in the order they appear (using length order, lexicographic order), that is, 1 is mapped to 1, 10 is mapped to 2. And 100, 101 and 1000 are mapped to 3, 4 and 5, respectively. You are to write a program to generate Pinary number representations for integers given. 

Input

Your program is to read from standard input. The input consists of T test cases. The number of test cases T is given in the first line of the input. Each test case starts with a line containing a postive integer 2 < K < 90, 000, 000 . 

Output

Your program is to write to standard output. Print exactly one line for each test case. For each test case, print the Pinary number representation for input integer. The following shows sample input and output for three test cases. 

Sample Input

3 7 2000 22

Sample Output

1010 1001000001001000 1000001

思路分析:

题目的意思是说,Pinary这个数是一个正数而且只由0和1构成,而且开头不能为零,两个1不能连续出现,要求给你一个次序求出这个次序所在的Pinary数。

这个题目需要自己去耐心找规律,对于Pinary数,前几项为1,10,100,101,1000,1001,1010,10000,10001,10010,10100,10101。。。。。若从位数的角度分析,可得位数为1,2,3,4,5的分别有1,1,2,3,5个,后面归纳可得这是一个斐波那契数列,即a[i]=a[i-1]+a[i-2]。得出上面的规律之后就可以大致确定次序为n的Pinary数的位置。根据斐波那契数列的特殊性,即类似递归的生成之后的所有数,可知对于一个给定的次序n,n=x1*F(1)+x2*F(2)+x3*F(3)+....+xi*F(i),其中xi为0或1,且xi和xi+1不能同时为1,F(i)为第i个斐波那契数。例如,给定次序9,从44(根据具体情况确定)倒序,直到找到F(6)=8<=9(F(7)=13>9,因此9不可能由13以内(包括13)的斐波那契数构成),对于9,仅有:

9=1*8(因为第一个数必须为1)+0*5+0*3+0*2+1*1。对于一般情况,对于给定次序n,先从斐波那契数列中找到a[k]<=n,然后直接输出1,再令n=n-a[k],在n找到a[k’]满足n>=a[k’]之前,一直输出0,同时k--,。。。。。循环即可。

代码如下

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cmath>

#include <cstring>

#include <string>

#include <map>

#include <set>

#include <vector>

#include <stack>

#include <queue>

#include <algorithm>

using namespace std;

int main()

{

  int t,n,flag;

long long a[45];

a[0]=1;

a[1]=1;

  for(int i=2;i<45;i++)

  a[i]=a[i-1]+a[i-2];

  scanf("%d",&t);

  while(t--)

{

   scanf("%d",&n);

   int k=44;

flag=0;

   while(k>0)

{

    if(n >= a[k])

   {

     flag=1;

     n-=a[k];

     printf("1");

    }

    else

   {

     if(flag == 1)//防止未找到“第一个”1之前输入0

     printf("0");

    }

    k--;

   }

   printf("\n");

  }

  return 0;

}

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值