hdu4099 Revenge of Fibonacci

题意:给定fibonacci数列,输入前缀,求出下标。题目中fibonacci数量达到100000,而题目输入的前缀顶多为40位数字,这说明我们只需要精确计算fibinacci数前40位即可。查询时使用字典树。在计算时,为了保证前40位精确无误。在此我计算了前60位。以保证前面不在进位。

注意点:

1)关于表示进位问题,需要控制计算的数位数在60以内,切记计算时不要错位(相同位要对齐)。

2)坑点:题目给出的数插入字典树最好插入前40位即可,否则MLE.

3)坑点:题目只要求计算下标不超过100000,计算到100000或者以上均会WA,因为输出值不是-1

下面是数组的AC代码:824ms

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<string>
#include<map>
#include<fstream>
#include<ctime>
#include<queue>
#include<vector>
#include<numeric>
#include<string.h>
#include<iomanip>
#include<sstream>
#include<algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef vector<int> BigInterger;
const int maxn = 100000;
const int maxsize = 10;
const int maxnum =65;

struct TrieNode{
	TrieNode(int d = -1) :id(d){ memset(next, NULL, sizeof(next)); }
	int id;
	TrieNode*next[maxsize];
};
TrieNode*T = new TrieNode;

void insert(char*str,const int&index){
	int len = strlen(str);
	TrieNode*p = T;
	int t = 0;
	for (int i = len-1; i>=0&&t<40;i--,t++){
		int id =str[i]-‘0‘;
		if (!p->next[id])p->next[id] = new TrieNode(index);
		p = p->next[id];
	}
}

int search(char*str){
	TrieNode*p = T;
	while (*str != ‘\0‘){
		int id = *str++ - ‘0‘;
		if (!p->next[id])return -1;
		p = p->next[id];
	}
	return p->id;
}
void init(){
	char f[3][maxnum];
	f[1][0] =‘1‘; f[1][1] = ‘\0‘;
	f[0][0] =‘1‘; f[0][1] = ‘\0‘;
	insert("1", 0);
	for (int i = 2; i<maxn; i++){
		int g = 0,j=0,cnt = 0, x;
		int r1 = (i - 1) % 3, r2 = (i - 2) % 3, r = i % 3;
		int lena = strlen(f[r1]);
		int lenb = strlen(f[r2]);
		if (lena >= maxnum - 5){
			memcpy(f[r1], f[r1]+1, lena - 1); f[r1][lena - 1] = ‘\0‘;
			memcpy(f[r2], f[r2]+1, lenb - 1); f[r2][lenb - 1] = ‘\0‘;
			lena--, lenb--;
		}
		while (g || j < lena||j<lenb){
			x = g;
			if (j < lena)x += f[r1][j]-‘0‘;
			if (j < lenb)x += f[r2][j]-‘0‘;
			f[r][cnt++] = x % 10+‘0‘;
			g = x / 10;
			j++;
		}
		f[r][cnt] = ‘\0‘;
		insert(f[r], i);
	}
}
int main(){
	init();
	int T,kase=1;
	char str[50];
	scanf("%d", &T);
	while(T--){
		scanf("%s", str);
		printf("Case #%d: %d\n",kase++,search(str));
	}
	return 0;
}

 采用向量AC的代码624ms(传值要用引用,否则多了不必要的复制):

#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<string>
#include<map>
#include<fstream>
#include<ctime>
#include<queue>
#include<vector>
#include<numeric>
#include<string.h>
#include<iomanip>
#include<sstream>
#include<algorithm>
using namespace std;
typedef pair<int,int> PII;
typedef vector<int> BigInterger;
const int maxn = 100000;
const int maxsize = 10;
const int maxnum =65;

struct TrieNode{
	TrieNode(int d = -1) :id(d){ memset(next, NULL, sizeof(next)); }
	int id;
	TrieNode*next[maxsize];
};
TrieNode*T = new TrieNode;

void insert(const BigInterger&v,const int&index){
	int len=v.size();
	TrieNode*p = T;
	int t = 0;
	for (int i = len-1; i>=0&&t<40;i--,t++){
		int id =v[i];
		if (!p->next[id])p->next[id] = new TrieNode(index);
		p = p->next[id];
	}
}

int search(char*str){
	TrieNode*p = T;
	while (*str != ‘\0‘){
		int id = *str++ - ‘0‘;
		if (!p->next[id])return -1;
		p = p->next[id];
	}
	return p->id;
}
//引用传值,避免赋值,效率更高
void add(BigInterger &a, BigInterger &b, BigInterger&c){
	int lena = a.size(), lenb = b.size();
	int g=0, x,i=0;
	c.clear();
	if (lena > maxnum - 5 || lenb > maxnum - 5){
		a.erase(a.begin()), b.erase(b.begin());
		lena--, lenb--;
	}
	while (g || i < lena || i < lenb){
		x = g;
		if (i < lena)x += a[i];
		if (i < lenb)x += b[i];
		c.push_back(x % 10);
		g = x / 10;
		i++;
	}
}
void init(){
	BigInterger a[3];
	a[0].push_back(1);
	a[1].push_back(1);
	insert(a[1], 0);
	for (int i = 2; i<maxn; i++){
		add(a[(i - 1) % 3], a[(i - 2) % 3], a[i % 3]);
		insert(a[i % 3], i);
	}
}
int main(){
	init();
	int T,kase=1;
	char str[50];
	scanf("%d", &T);
	while(T--){
		scanf("%s", str);
		printf("Case #%d: %d\n",kase++,search(str));
	}
	return 0;
}

  

 

时间: 2024-08-28 11:55:36

hdu4099 Revenge of Fibonacci的相关文章

HDU4099 Revenge of Fibonacci(高精度+Trie)

Revenge of Fibonacci Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 204800/204800 K (Java/Others) Total Submission(s): 2582    Accepted Submission(s): 647 Problem Description The well-known Fibonacci sequence is defined as following: Here w

HDU 4099 Revenge of Fibonacci

Revenge of Fibonacci Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 204800/204800 K (Java/Others) Total Submission(s): 2027    Accepted Submission(s): 475 Problem Description The well-known Fibonacci sequence is defined as following: Here w

Revenge of Fibonacci(杭电5018)

Revenge of Fibonacci Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 721    Accepted Submission(s): 332 Problem Description In mathematical terms, the sequence Fn of Fibonacci numbers is define

HDU 4099 Revenge of Fibonacci Trie+高精度

Revenge of Fibonacci Problem Description The well-known Fibonacci sequence is defined as following: Here we regard n as the index of the Fibonacci number F(n).  This sequence has been studied since the publication of Fibonacci's book Liber Abaci. So

HDOJ 题目1789 Revenge of Fibonacci(大数, 字典树)

Revenge of Fibonacci Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 204800/204800 K (Java/Others) Total Submission(s): 2405    Accepted Submission(s): 609 Problem Description The well-known Fibonacci sequence is defined as following: Here w

hdu 4099 Revenge of Fibonacci Trie树与模拟数位加法

Revenge of Fibonacci 题意:给定fibonacci数列的前100000项的前n位(n<=40);问你这是fibonacci数列第几项的前缀?如若不在前100000项范围内,输出-1: 思路:直接使用数组模拟加法,再用Trie树插入查找即可:但是一般使用new Trie()的代码都是MLE的.反而我之前写的,直接得到数组大小的maxnode版本的内存可以接受:并且还有一点就是前40位的精度问题:由于是自己计算出来的finboncci数列,并不是系统给的,所以1的进位不会形成递推

hdu 5018 Revenge of Fibonacci(BestCoder Round #10)

Revenge of Fibonacci Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 372    Accepted Submission(s): 177 Problem Description In mathematical terms, the sequence Fn of Fibonacci numbers is define

hdu 4099 Revenge of Fibonacci(字典树)

Revenge of Fibonacci Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 204800/204800 K (Java/Others) Total Submission(s): 2355    Accepted Submission(s): 587 Problem Description The well-known Fibonacci sequence is defined as following: Here w

hrbust 1209/hdu 4099 Revenge of Fibonacci【字典树+大数】

Revenge of Fibonacci Time Limit: 5000 MS Memory Limit: 204800 K Total Submit: 37(24 users) Total Accepted: 18(17 users) Rating:  Special Judge: No Description The well-known Fibonacci sequence is defined as following: F(0) = F(1) = 1 F(n) = F(n - 1)