http://acm.hdu.edu.cn/showproblem.php?pid=4099
题意很简单,就是让你在字典树上跑大斐波那契………只不过我们不能完全按照他题意的意思做0 0 因为据说10W位的斐波那契数有2W位0……0蛋疼…………因此我们只要把数据控制在前40位就行,但是存储的时候还是要存储前60位这样如果出现了那种奇葩的数 假设第57位和第58位相加后会导致所有位向前进一位…………0^0 想想都烦……所以我干脆把位数存储在第60位即可。
杭电应该是改数据了,这题我曾经MLE了10多次结果这次拿之前代码直接过了 7……7
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#define maxs 1000010
#define MME(i,j) memset(i,j,sizeof(i))
using namespace std;
char FB[3][104];
typedef struct node
{
struct node *nexts[10];
int id;
} Trienode,*Trie;
Trie buildNode()
{
Trie p=new node;
MME(p->nexts,0);
p->id=-1;
return p;
}
void inser(char *s,Trie root,int num)
{
int i=0,id,len=strlen(s);
Trie p=root;
for(int i=0; i<len&&i<41; i++)
{
id=s[i]-'0';
if(p->nexts[id]==NULL)
p->nexts[id]=buildNode();
p=p->nexts[id];
if(p->id<0)
p->id=num;
}
if(p->id<0)
p->id=num;
//printf("%d\n",p->id);
}//建树过程
int finds(char *s,Trie root)
{
int i=0,id;
while(s[i])
{
id=s[i]-'0';
if(root->nexts[id]==NULL)
return -1;
root=root->nexts[id];
i++;
}
return root->id;
}//查询过程
void str_add(char *a,char *b,char *c)//大数加法- -我们只要3个数组就行开多了反而MLE
{
char temp[200];
int lena=strlen(a),lenb=strlen(b);
int a_pos=lena-1,b_pos=lenb-1,idxa,idxb;
int k=0,jinwei=0;
while(a_pos>=0||b_pos>=0)
{
if(a_pos<0)idxa=0;
else idxa=a[a_pos]-'0';
if(b_pos<0)idxb=0;
else idxb=b[b_pos]-'0';
int sum=idxa+idxb+jinwei;
temp[k++]=(sum%10)+'0';
jinwei=(idxa+idxb+jinwei)/10;
a_pos--;
b_pos--;
}
if(jinwei)
temp[k++]=jinwei+'0';
temp[k]='\0';
for(int i=0; i<k; i++)
c[i]=temp[k-1-i];
c[k]='\0';
return;
}
void deletetree(Trie root)
{
for(int i=0; i<10; i++)
{
if(root->nexts[i])
deletetree(root->nexts[i]);
}
delete root;
}
int main()
{
int times=1;
Trie root=buildNode();
FB[0][0]='1';
FB[0][1]='\0';
inser(FB[0],root,0);
FB[1][0]='1';
FB[1][1]='\0';
int len1,len2;
for(int i=2; i<100000; i++)
{
len1=strlen(FB[0]);
len2=strlen(FB[1]);// len 2>60 因为虽然我们只要40位但是如果出现了及其特别的数比如后面相加后都可以进一位那么会让最后的结果又差异
if(len2>60)//因为第10W个 FB数大约有 2W 位,那么运用大数加法会变得特慢
{
FB[0][len1-1]=0;
FB[1][len2-1]=0;
}
str_add(FB[0],FB[1],FB[2]);
inser(FB[2],root,i);
strcpy(FB[0],FB[1]);
strcpy(FB[1],FB[2]);
}//初始化前10W个
int t;
while(~scanf("%d",&t))
{
int ans;
while(t--)
{
scanf("%s",FB[0]);
ans=finds(FB[0],root);
printf("Case #%d: %d\n",times++,ans);
}
}
deletetree(root);
return 0;
}