HDU_How Many Fibs求数列区间数目
题目传送门:
http://acm.hdu.edu.cn/showproblem.php?pid=1316
还是练练手,因为对Java本身都还不是太熟。这个题唯一的有意思的问题就是边界范围是10^100数量级,数组边界是多少呢?
规定fib(1),fib(2)是1,2,那么纵观这个数列
1,2,3,5,8,13
5个数加一个位
5个数加一个位
1,2,3,5,8,13,21,起始的是1和2,下一个位的起始是13和21,不论怎么看都比5个进1位要快
所以后面肯定是越来越快的
所以后面肯定是越来越快的
10^100次方是100位,100*5=500,后面不可能出现个位数连续是1,1的,因为1+?没有是?1的,所以顶天边界到500.那么就简单了。。。
import java.math.BigInteger;
import java.util.Scanner;
import java.math.BigDecimal;
public class Main
{
public static void main(String args[])
{
Scanner in = new Scanner(System.in);
BigInteger fib[] = new BigInteger[506];
fib[1] = new BigInteger("1");
fib[2] = new BigInteger("2");
for(int i = 3; i <= 505; i++) {
fib[i] = fib[i-1].add(fib[i-2]);
}
while(in.hasNext()){
BigInteger a,b;
int sum = 0;
a = in.nextBigInteger();
b = in.nextBigInteger();
if(a.equals(BigInteger.ZERO)&&b.equals(BigInteger.ZERO))
break;
for(int i = 1; i <= 505; i++) {
if((fib[i].compareTo(a)==1||fib[i].compareTo(a)==0)&&(fib[i].compareTo(b)==-1||fib[i].compareTo(b)==0))
sum++;
}
System.out.println(sum);
}
}
}
附上一个C/C++版本:
#include<iostream>
#include <stdio.h>
#include<string>
using namespace std;
string add(string x,string y)
{
string ans ;
int lenx = x.length();
int leny = y.length();
if(lenx<leny)
{
for(int i = 1;i<=leny-lenx;i++)
x = "0"+x;
}
else
{
for(int i = 1;i<=lenx-leny;i++)
y = "0"+y;
}
lenx = x.length();
int cf = 0;
int temp;
for(int i = lenx-1;i>=0;i--)
{
temp = x[i] - '0' + y[i] - '0'+cf;
cf = temp/10;
temp%=10;
ans = char('0'+temp)+ans;
}
if(cf!=0)
ans = char(cf+'0')+ans;
return ans;
}
int compare(string x,string y)// 字符串形式的数的比较大小
{
int i,lenx = x.length(),leny = y.length(),leaf;
if(x==y) return 0;// 0 表示 x == y
if(x.length()>y.length()) return 1;// 返回1 表示 x > y
if(x.length()<y.length()) return -1;// -1 表示 x < y
if(x.length()==y.length())
{
for(i = 0;i<lenx;i++)
{
if(x[i]==y[i]) continue;
if(x[i]>y[i]) return 1;
else return -1;
}
return 0;
}
return leaf;
}
int main()
{
int i,j,k,start,eend;
string x,y,num[1005];;
num[0] = "0";
num[1] = "1";
num[2] = "2";
for(int i = 3;i<=1000;i++)
num[i] = add(num[i-1],num[i-2]);
while(cin>>x>>y&&x!="0"||y!="0")// x y 均为 0 的时候才结束程序
{
if(y == "0")// y == 0 时 直接输出 0
{
printf("0");
continue;
}
start = eend = 0;
/**
j = k = 0;
while(x[j]=='0')// 受到
j++;
x = x.substr(j,x.length()-j);// 受到 hdu 1753 的影响,以为会有前导0,其实没有
while(y[k]=='0')
k++;
y = y.substr(k,y.length()-k);
**/
for(i = 1;i<1000;i++)
{
if(compare(x,num[i])==0)
{
start = i;
break;
}
else if(compare(num[i],x)==-1&&compare(num[i+1],x)==1)
{
start = i+1;
break;
}
}
for(i = 1;i<1000;i++)
{
if(compare(y,num[i])==0){
eend = i;break;
}
else if(compare(num[i],y)==-1&&compare(num[i+1],y)==1){
eend = i;break;
}
}
if(x=="0") // 注意 x == 0 时的情况
start = 1;
//cout<<start<<" "<<eend<<endl;;
cout<<eend-start+1<<endl;
}
}
浙公网安备 33010602011771号