[刷题]算法竞赛入门经典(第2版) 5-15/UVa12333 - Revenge of Fibonacci
题意:在前100000个Fibonacci(以下简称F)数字里,能否在这100000个F里找出以某些数字作为开头的F。要求找出下标最小的。没找到输出-1。
代码:(Accepted,0.250s)
//UVa12333 - Revenge of Fibonacci
//Accepted 0.250s
//#define _XIENAOBAN_
#include<iostream>
#include<cstring>
#define MAXS 0xffffff
#define CIN 50
using namespace std;
struct EACH_DIGIT {
int id;
bool flag;
EACH_DIGIT* next[10];//0~9
}nodes[MAXS];
class DIC_TREE {
int index;
EACH_DIGIT* ini;
public:
DIC_TREE() :index(0), ini(nodes) {}
void insert(const int* F, int d, const int& n) {
EACH_DIGIT* p(ini);
int brk(d > 41 ? d - 41 : 0);
while (d-- > brk) {
if (p->next[F[d]] == nullptr)
p->next[F[d]] = nodes + (++index);
if (!p->flag && !p->id) p->id = n;
p = p->next[F[d]];
}
if (!p->flag) p->flag = true, p->id = n;
}
int search(const int* F) {
EACH_DIGIT* p(ini);
for (int i(0);F[i] != -1;++i) {
if (p->next[F[i]] == nullptr) return -1;
p = p->next[F[i]];
}
return p->id;
}
}dic;
int Fnum[2][21000];//In average, Fibonacci numbers in each digit is about 5, 21000 > (100000/5)
int T, N, SN[CIN];
char S[CIN];
int main()
{
#ifdef _XIENAOBAN_
#define gets(T) gets_s(T, 66666)
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif
memset(Fnum, 0, sizeof(Fnum));
memset(nodes, 0, sizeof(nodes));
int dgt(1);
Fnum[0][0] = Fnum[1][0] = 1;
dic.insert(Fnum[0], dgt, 0);
for (int n(2);n < 100000;++n) {
int two(n % 2), one((two + 1) % 2);//two:F(n-2)(also means the place of F(n)) one:F(n-1)
for (int i(dgt < 51 ? 0 : dgt - 51);i < dgt;++i)
if ((Fnum[two][i] += Fnum[one][i])>9)
Fnum[two][i] -= 10, Fnum[two][i + 1] += 1;
if (Fnum[two][dgt]) ++dgt;
dic.insert(Fnum[two], dgt, n);
}
while (scanf("%d", &T) != EOF)//Start to handle cases
for (N = 1;N <= T;++N) {
scanf("%s", S);
int i(0);
for (;S[i];++i) SN[i] = S[i] - 48;
SN[i] = -1;
printf("Case #%d: %d\n", N, dic.search(SN));
}
return 0;
}
分析:暴力求出前100000个F数字的话妥妥地超时。我一开始也想只取前面多少位以减少计算,担心出现99999…999什么什么的情况,导致精度不对,但看网上取50位的都过了,那就不虚了。
思路是用树的结构,每一位数(next)为一个结点,每个结点还储存“遍历到当前位数时满足的最小的F下标(index)”。若某个F刚好遍历到当前结点时结束,则修改当前结点index为当下F下标,并将其置为不可修改状态(flag:=true;)。若F遍历到当前还未结束,则若当前下标小于已储存下标且flag=false,则修改当前index。其实很好理解,但我好像说的不太清楚。
这题并没用到STL,看网上也是这样。数据结构的组建参考了 http://blog.csdn.net/a197p/article/details/44170921 。真的只是大概的看两眼那两个结构体,看了两眼想自己思考实现出来,但最后自己实现出来发现结构体里的变量和他的一样,最好的实现方法也只能是这样。最神奇的是甚至insert函数和search(他的query)函数和我的都和他写的一样—。—
但是他的代码就是0.130s,而我的时间是他的两倍,明明差不多我却没找出多在哪里。但是大神的代码里有好多巧妙的地方,比如他的
tnode dict[nodesize];//line 14
tnode* newnode() { return &dict[size++]; }//line 31
这样就免去了每次都new,节约时间还免去了delete的烦恼,厉害了。于是毫不犹豫抄过来。再比如他的
memset(dict,0,sizeof(dict));//line 28
我一开始是在struct EACH_DIGIT 里面写了个构造函数
EACH_DIGIT():flag(0),id(0){memset(next,NULL,sizeof(next));}
但是发现他一个memset全设为0和我效果不是一样的嘛。刷过去还快。
[刷题]算法竞赛入门经典(第2版) 5-15/UVa12333 - Revenge of Fibonacci的更多相关文章
- [刷题]算法竞赛入门经典(第2版) 4-6/UVa508 - Morse Mismatches
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,10 ms) //UVa508 - Morse Mismatches #include< ...
- [刷题]算法竞赛入门经典(第2版) 5-13/UVa822 - Queue and A
题意:模拟客服MM,一共有N种话题,每个客服MM支持处理其中的i个(i < N),处理的话题还有优先级.为了简化流程方便出题,设每个话题都是每隔m分钟来咨询一次.现知道每个话题前来咨询的时间.间 ...
- [刷题]算法竞赛入门经典(第2版) 4-5/UVa1590 - IP Networks
书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) //UVa1590 - IP Networks #include<iost ...
- [刷题]算法竞赛入门经典(第2版) 6-7/UVa804 - Petri Net Simulation
题意:模拟Petri网的执行.虽然没听说过Petri网,但是题目描述的很清晰. 代码:(Accepted,0.210s) //UVa804 - Petri Net Simulation //Accep ...
- [刷题]算法竞赛入门经典(第2版) 6-6/UVa12166 - Equilibrium Mobile
题意:二叉树代表使得平衡天平,修改最少值使之平衡. 代码:(Accepted,0.030s) //UVa12166 - Equilibrium Mobile //Accepted 0.030s //# ...
- [刷题]算法竞赛入门经典(第2版) 6-1/UVa673 6-2/UVa712 6-3/UVa536
这三题比较简单,只放代码了. 题目:6-1 UVa673 - Parentheses Balance //UVa673 - Parentheses Balance //Accepted 0.000s ...
- [刷题]算法竞赛入门经典(第2版) 5-16/UVa212 - Use of Hospital Facilities
题意:模拟患者做手术. 其条件为:医院有Nop个手术室.准备手术室要Mop分钟,另有Nre个恢复用的床.准备每张床要Mre分钟,早上Ts点整医院开张,从手术室手术完毕转移到回复床要Mtr分钟.现在医院 ...
- [刷题]算法竞赛入门经典(第2版) 5-11/UVa12504 - Updating a Dictionary
题意:对比新老字典的区别:内容多了.少了还是修改了. 代码:(Accepted,0.000s) //UVa12504 - Updating a Dictionary //#define _XieNao ...
- [刷题]算法竞赛入门经典(第2版) 5-10/UVa1597 - Searching the Web
题意:不难理解,照搬题意的解法. 代码:(Accepted,0.190s) //UVa1597 - Searching the Web //#define _XIENAOBAN_ #include&l ...
随机推荐
- BrowserSync的安装和使用
BrowserSync真是前端必备神器,浏览器同步工具.简单来说就是当你保存文件的同时浏览器自动刷新网页,省去了手动的环节,大大的节省了开发时间,这个工具是基于nodejs的,可以通过npm安装,不在 ...
- 【转】关于swf安全沙箱冲突:不能被本地访问
错误提示:SWF 文件不能被本地访问 不能访问本地只有仅限于文件系统的 SWF 文件和可信的本地 SWF 文件可以访问本地资源 错误信息:SecurityError:Error #2148: SWF ...
- webpack点滴记录
有了webpack..(不借助gulp/grunt)代码压缩 图片base64,解析less/sass coffee css压缩,MD5加密都帮你做了..还支持按需加载..还有热替换 webpack常 ...
- ngrok把本地主机映射到公网域名
这两天又要搞微信项目,然后我下载了一个QQ浏览器,搜索微信调试工具,我再搜,再搜,搜不出来,问了下客服,暂时下架了,好吧! 我上网搜了一下,就找到了 ngrok 这个东西,它也可以把你本地主机映射到 ...
- sleep()和wait()的区别 --- 快入睡了,突然想起一个知识点,搞完就睡
自从开了博客之后,大部分是转发的,不断的ctrl+c和ctrl+v,知识是越屯越多,吸收的却很少,后来越来越懒,直接保存链接了. 我已经认识到了自己的错误,自己查询到的这些知识,以后还是会定期保存的, ...
- 关于C++ 循环
有的时分,可能需求屡次履行同一块代码.通常情况下,句子是顺序履行的:函数中的第一个句子先履行,接着是第二个句子,依此类推. 编程言语供给了答应更为杂乱的履行途径的多种操控结构. 循环句子答应咱们屡次履 ...
- codevs2019 Uva10029 递变阶梯
提交地址:[codevs][Uva] 题目描述 递变是指通过增加.减少或改变单词x中的一个字母,使它变成字典中的另一个单词y.比如将dig变成dog,将dog变成do都是递变.递变阶梯是一个按字典序 ...
- Sublime text3 设置的中文翻译
// While you can edit this file, it's best to put your changes in // "User/Preferences.sublime- ...
- 如何做到机器学习竞赛Kaggle排名前2%
原创文章,同步首发自作者个人博客 .转载请务必在文章开头显眼处注明出处 摘要 本文详述了如何通过数据预览,探索式数据分析,缺失数据填补,删除关联特征以及派生新特征等方法,在Kaggle的Titanic ...
- Ranklib源码剖析--LambdaMart
Ranklib是一套优秀的Learning to Rank领域的开源实现,其中有实现了MART,RankNet,RankBoost,LambdaMart,Random Forest等模型.其中由微软发 ...