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;
}