二分查找+大整數加法——Poj 2413 How many Fibs?

How many Fibs?
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9710   Accepted: 3622

Description

Recall the definition of the Fibonacci numbers: 
f1 := 1 

f2 := 2 

fn := fn-1 + fn-2     (n>=3) 

Given two numbers a and b, calculate how many Fibonacci numbers are in the range [a,b].

Input

The input contains several test cases. Each test case consists of two non-negative integer numbers a and b. Input is terminated by a=b=0. Otherwise, a<=b<=10100. The numbers a and b are given with no superfluous leading zeros.

Output

For each test case output on a single line the number of Fibonacci numbers fi with a<=fi<=b.

Sample Input

10 100
1234567890 9876543210
0 0

Sample Output

5
4

思路:

首先算出前480個斐波那契數(第480個斐波那契數的位數101位,滿足題目要求的數據範圍),然後使用二分查找確定a和b在斐波那契數列的位置,兩位置做差,即爲中間包含的斐波那契數個數,注意a和b也是斐波那契數時,輸出結果特殊處理下。


#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

#define MAXN	500
#define MAXLEN	110
#define LAST MAXLEN-2

char store[MAXN][MAXLEN];	//存儲MAXN個斐波那契數
char *Fibs[MAXN];		//存儲每個斐波那契數的首地址

//大整數相加
char* IntAddition(char *a, char *b, char *sum)
{
	int i, j, k, first;

	//從末位開始,把a與b對應位的和存入sum中,暫不處理進位
	for (i = strlen(a)-1, j = LAST; i >= 0; i--, j--)
	{
		sum[j] = a[i] - '0';
	}
	for (i = strlen(b)-1, k = LAST; i >= 0; i--, k--)
	{
		sum[k] += b[i] - '0';
	}

	//獲取sum中結果的首位位置
	first = j < k ? j : k;

	//處理進位
	for (i = LAST; i >= first; i--)
	{
		sum[i-1] += sum[i] / 10;
		sum[i] = sum[i] % 10 + '0';
	}
	//去除前導'0'
	while (sum[first] == '0' && first < LAST)
	{
		first++;
	}
	//返回sum的首位地址
	return &sum[first];
}

//計算485個斐波那契數
void Fibonacci(void)
{
	memset(store, 0, sizeof(store));
	memset(Fibs, NULL, sizeof(Fibs));

	strcpy(store[1], "1");
	strcpy(store[2], "2");
	Fibs[1] = store[1];
	Fibs[2] = store[2];

	int i;
	for (i = 3; i < 485; i++)
	{
		Fibs[i] = IntAddition(Fibs[i-2], Fibs[i-1], store[i]);
	}
}

int Compare(char *a, char *b)
{
	int lenA = strlen(a);
	int lenB = strlen(b);

	if (lenA == lenB)
	{
		return strcmp(a, b);
	}
	return lenA > lenB ? 1 : -1;
}

int BinarySearch(char *num, bool &flag)
{
	int low = 1;
	int high = 480;
	
	while (low <= high)
	{
		int mid = (low + high) / 2;
		
		int res = Compare(num, Fibs[mid]);
		if (res == 0)
		{
			flag = true; return mid;
		}
		else if (res < 0)
		{
			high = mid - 1;
		}
		else
		{
			low = mid + 1;
		}
	}
	return low;
}

int main(void)
{
	Fibonacci();

	char a[MAXLEN], b[MAXLEN];
	while (scanf("%s %s", a, b) != EOF)
	{
		if (strcmp(a, "0") == 0 && strcmp(b, "0") == 0)
		{
			break;
		}

		bool flagLeft = false;
		bool flagRight = false;
		//分別找出a和b在斐波那契數中的位置
		//當查找的數不是斐波那契數時,二分查找返回的位置是第一個比它大的斐波那契數的位置
		int left = BinarySearch(a, flagLeft);
		int right = BinarySearch(b, flagRight);

		//當b也是斐波那契數時,要把兩位置的差值加1
		if (flagRight)
		{
			printf("%d\n", right - left + 1);
		}
		else
		{
			printf("%d\n", right - left);
		}
	}
	return 0;
}


發佈了66 篇原創文章 · 獲贊 31 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章