问题描述
小蓝定义了一个 Fibonacci 集合 F,集合的元素如下定义:
最小的 5 个 Fibonacci 数 1, 2, 3, 5, 8 属于集合 F。
如果一个元素 x 属于 F,则 3x + 2、5x + 3 和 8x + 5 都属于集合 F。
其他元素都不属于 F。
请问,这个集合中的第 2020 小元素的值是多少?
答案提交
这是一道结果填空的题,你只需要算出结果后提交即可。
本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
总结反思:
这道题看起来很简单,其实很多细节在里面。。。。
这道题用数组做也是可以的,就是每次都需要找最小值的时候会很麻烦且易错(一开始就是使用数组做的,结果每一个对的。。。。)
题意:
给一个集合和一些集合里面的元素,要求根据公式求出集合里的第2020小的元素。
思路:
这道题很适合优先队列使用,每次取出最小的元素,根据公式求出另一个元素,判断另一个元素有没有出现过,没有出现过就入队。当取出的是2020个元素的时候,就是答案了。
注意:
1、这道题尽量记录当前取出的是那一次最小的元素(刚开始一直想直接在添加的时候求出答案,结果很是混乱)
2、队列默认大根堆(从大到小取),在定义优先队列的时候,需要记得小根堆(从小到大取)使用的语法:priority_queue + < + 类型 + 逗号 + vector + < + ll +> + 逗号+ greater + < + 类型 + > > +优先队列变量名+分号
3、 优先队列队首是 top()
4、这道题真的很容易出错,也不知道怎么检验答案(如果有人知道,请留言~),就需要很小心很严谨!!!
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <iostream>
#include <string.h>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
using namespace std;
#define ll long long
ll vis[100000000];
priority_queue<ll,vector<ll>,greater<ll> >q;
int main() {
// cout<<41269<<endl;
// return 0;
q.push(1);
q.push(2);
q.push(3);
q.push(5);
q.push(8);
vis[1]=vis[2]=vis[3]=vis[5]=vis[8]=1;
ll cnt=0;//记录第几次取出最小的值
while(!q.empty()) {
ll temp=q.top();//优先队列是top
cnt++;
if(cnt==2020) {
cout<<temp<<endl;
break;
}
q.pop();
ll x;
x=temp*3+2;
if(!vis[x]) {
q.push(x);
vis[x]=1;
}
x=temp*5+3;
if(!vis[x]) {
q.push(x);
vis[x]=1;
}
x=temp*8+5;
if(!vis[x]) {
q.push(x);
vis[x]=1;
}
}
return 0;
}