有多少个斐波那契子数列(微软笔试题)
2015-10-06 16:06
549 查看
题目链接:http://hihocoder.com/contest/mstest2015sept2/problem/3
题目:
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
Given a sequence {an}, how many non-empty sub-sequence of it is a prefix of fibonacci sequence.
A sub-sequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements.
The fibonacci sequence is defined as below:
F1 = 1, F2 =
1
Fn = Fn-1 +
Fn-2, n>=3
One line with an integer n.
Second line with n integers, indicating the sequence {an}.
For 30% of the data, n<=10.
For 60% of the data, n<=1000.
For 100% of the data, n<=1000000, 0<=ai<=100000.
One line with an integer, indicating the answer modulo 1,000,000,007.
The 7 sub-sequences are:
{a2}
{a3}
{a2, a3}
{a2, a3,
a4}
{a2, a3,
a5}
{a2, a3,
a4, a6}
{a2, a3,
a5, a6}
样例输入
样例输出
分析:
寻找有多少个斐波那契子数列,有一些和此类似的问题,比如最长递增子序列,最大子串和。
而本题和它们都不太一样,因为最长递增子序列是只要递增的,不用连续,本题需要的是固定次序的,不用连续的子序列,也就是说前后的顺序是固定的。
建议大家一定要先看一下我以前写的PAT的一道题:http://blog.csdn.net/apie_czx/article/details/48299649(有多少个PAT)
本题只是相当于它的扩展。
维护一个计数数组,每一项分别对应固定次序中以每个数结尾的子序列项//*point
比如,在本题,我们维护一个cc[1000]数组,cc[1]对应以1结束的长度为1的子序列的数量
cc[2]对应着以1结束的长度为2的子序列的数量
cc[3]对应着以2结束的长度为3的子序列的数量
cc[4]对应着以3结束的长度为4的子序列的数量
cc[5]对应着以5结束的长度为5的子序列的数量
cc[6]对应着以8结束的长度为6的子序列的数量
所以,对于输入的数列,我们先对其过滤一遍,除去不在斐波那契数列中的数字,
然后对于当前数字V[i],如果它对应斐波那契中的fibo[idx],那么我们就进行一下操作:
cc[idx] += cc[idx - 1],因为我们要把cc[idx - 1]代表着前面以fibo[idx - 1]结尾的子序列有cc[idx - 1]个,而它们和当前的V[i]组合刚好就是cc[idx]增加的量。
特别得:对于V[i] == 1的情况,我们需要先cc[2] += cc[1],在把cc[1] ++,因为1既是fibo[1]也是fibo[2]。
AC代码:
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<math.h>
#include<climits>
#include<map>
using namespace std;
const int NUM = 10000;
int fibo[NUM];//存放斐波那契数列
int cc[NUM];//以当前斐波那契数列结果的子串的个数
map<int, int>fibo2idx;//斐波那契数和其对应的下标,比如5对应4,8对应5
int main(){
//freopen("F://Temp/input.txt", "r", stdin);
fibo[1] = fibo[2] = 1;
for (int i = 3; i < NUM; ++i){//求出斐波那契数列以及map的下标
fibo[i] = fibo[i - 1] + fibo[i - 2];
fibo2idx[fibo[i]] = i;
}
for (int i = 0; i < NUM; ++i){
cc[i] = 0;
}
int n;
cin >> n;
vector<int>V;
for (int i = 0; i < n; ++i){
int tmp;
cin >> tmp;
if (tmp == 1 || fibo2idx.find(tmp) != fibo2idx.end())//只把输入中在斐波那契数列中的数放入V中
V.push_back(tmp);
}
for (int i = 0; i < V.size(); ++i){
if (V[i] == 1){//当为1的时候很特别,因为它即可当做feibo[1],也同时是fibo[2]
cc[2] += cc[1];
cc[1] ++;
if (cc[1] >= 1000000007)
cc[1] %= 1000000007;
if (cc[2] >= 1000000007)
cc[2] %= 1000000007;
}
else if (fibo2idx.find(V[i]) != fibo2idx.end()){//说明是fibo的数
int idx = fibo2idx[V[i]];
cc[idx] += cc[idx - 1];//*point
if (cc[idx] >1000000007)
cc[idx] %= 1000000007;
}
}
int sum = 0;
for (int i = 0; i < NUM; ++i){//最后结果是cc累加的结果
sum += cc[i];
if (sum >= 1000000007)
sum %= 1000000007;
}
cout << sum << endl;
return 0;
}
——Apie陈小旭
题目:
题目3 : Fibonacci
时间限制:10000ms单点时限:1000ms
内存限制:256MB
描述
Given a sequence {an}, how many non-empty sub-sequence of it is a prefix of fibonacci sequence.A sub-sequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements.
The fibonacci sequence is defined as below:
F1 = 1, F2 =
1
Fn = Fn-1 +
Fn-2, n>=3
输入
One line with an integer n.Second line with n integers, indicating the sequence {an}.
For 30% of the data, n<=10.
For 60% of the data, n<=1000.
For 100% of the data, n<=1000000, 0<=ai<=100000.
输出
One line with an integer, indicating the answer modulo 1,000,000,007.
样例提示
The 7 sub-sequences are:{a2}
{a3}
{a2, a3}
{a2, a3,
a4}
{a2, a3,
a5}
{a2, a3,
a4, a6}
{a2, a3,
a5, a6}
样例输入
6 2 1 1 2 2 3
样例输出
7
分析:
寻找有多少个斐波那契子数列,有一些和此类似的问题,比如最长递增子序列,最大子串和。
而本题和它们都不太一样,因为最长递增子序列是只要递增的,不用连续,本题需要的是固定次序的,不用连续的子序列,也就是说前后的顺序是固定的。
建议大家一定要先看一下我以前写的PAT的一道题:http://blog.csdn.net/apie_czx/article/details/48299649(有多少个PAT)
本题只是相当于它的扩展。
维护一个计数数组,每一项分别对应固定次序中以每个数结尾的子序列项//*point
比如,在本题,我们维护一个cc[1000]数组,cc[1]对应以1结束的长度为1的子序列的数量
cc[2]对应着以1结束的长度为2的子序列的数量
cc[3]对应着以2结束的长度为3的子序列的数量
cc[4]对应着以3结束的长度为4的子序列的数量
cc[5]对应着以5结束的长度为5的子序列的数量
cc[6]对应着以8结束的长度为6的子序列的数量
所以,对于输入的数列,我们先对其过滤一遍,除去不在斐波那契数列中的数字,
然后对于当前数字V[i],如果它对应斐波那契中的fibo[idx],那么我们就进行一下操作:
cc[idx] += cc[idx - 1],因为我们要把cc[idx - 1]代表着前面以fibo[idx - 1]结尾的子序列有cc[idx - 1]个,而它们和当前的V[i]组合刚好就是cc[idx]增加的量。
特别得:对于V[i] == 1的情况,我们需要先cc[2] += cc[1],在把cc[1] ++,因为1既是fibo[1]也是fibo[2]。
AC代码:
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<math.h>
#include<climits>
#include<map>
using namespace std;
const int NUM = 10000;
int fibo[NUM];//存放斐波那契数列
int cc[NUM];//以当前斐波那契数列结果的子串的个数
map<int, int>fibo2idx;//斐波那契数和其对应的下标,比如5对应4,8对应5
int main(){
//freopen("F://Temp/input.txt", "r", stdin);
fibo[1] = fibo[2] = 1;
for (int i = 3; i < NUM; ++i){//求出斐波那契数列以及map的下标
fibo[i] = fibo[i - 1] + fibo[i - 2];
fibo2idx[fibo[i]] = i;
}
for (int i = 0; i < NUM; ++i){
cc[i] = 0;
}
int n;
cin >> n;
vector<int>V;
for (int i = 0; i < n; ++i){
int tmp;
cin >> tmp;
if (tmp == 1 || fibo2idx.find(tmp) != fibo2idx.end())//只把输入中在斐波那契数列中的数放入V中
V.push_back(tmp);
}
for (int i = 0; i < V.size(); ++i){
if (V[i] == 1){//当为1的时候很特别,因为它即可当做feibo[1],也同时是fibo[2]
cc[2] += cc[1];
cc[1] ++;
if (cc[1] >= 1000000007)
cc[1] %= 1000000007;
if (cc[2] >= 1000000007)
cc[2] %= 1000000007;
}
else if (fibo2idx.find(V[i]) != fibo2idx.end()){//说明是fibo的数
int idx = fibo2idx[V[i]];
cc[idx] += cc[idx - 1];//*point
if (cc[idx] >1000000007)
cc[idx] %= 1000000007;
}
}
int sum = 0;
for (int i = 0; i < NUM; ++i){//最后结果是cc累加的结果
sum += cc[i];
if (sum >= 1000000007)
sum %= 1000000007;
}
cout << sum << endl;
return 0;
}
——Apie陈小旭
相关文章推荐
- 微软无线镭射简报鲨8000激光笔记本鼠标 - (2)
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- 对《大家都在点赞 Windows Terminal,我决定给你泼一盆冷水》一文的商榷
- 微软镜像下载
- 微软公布2013年必应搜索十大首页美图
- 微软Word 2007数学插件 Microsoft Math 提供下载
- 巧用微软EWF来保护系统
- 微软又爆预留后门 警方可轻松获取硬盘资料
- 微软推DreamSpark计划为学生提供免费软件下载地址
- java实现斐波那契数列的3种方法
- java数学归纳法非递归求斐波那契数列的方法
- C++输出斐波那契数列的两种实现方法
- 求斐波那契(Fibonacci)数列通项的七种实现方法
- Linux Shell相关笔试题 一
- 月光微博客
- 月光微博客
- 月光微博客
- 月光微博客
- 月光微博客