题目
Description
假设该解说在第00分钟位于第00阶梯,第1,2,31,2,3分钟时位于第11阶梯,之后每一分钟处在的阶梯都是前三分钟的阶梯数之和,如第44分钟位于第33阶梯,第55分钟位于第55阶梯,第66分钟位于第99阶梯,注意他只会在整数分钟才会登上更高的阶梯,比如当他在3.53.5分钟时,他仍位于第11阶梯。小Y同学想知道该解说在第xx秒时的神力如何,所以请你告诉他第xx秒时该解说位于哪一级阶梯,为了防止他的神力过大,输出的答案对于425425取模。
Input
一个整数t( 0 \leq t \leq 10^8)t(0≤t≤10
8
)表示多少秒
Output
一个整数xx
表示当前取模后登上了哪一级阶梯。
分析
直接看题目的第三段,可以看出这是一个计算f(n)+f(n-1)+f(n-2)的递归问题,于是笔者刚开始就开了个巨大的数组,记录从f(1)到f(n)的值,并且没有没步取模。((⊙﹏⊙)),果不其然的就over了。
其实可以只记录下一步所需要用到的三个值(其实想想见过很多地方都是这样改进的,比如背包动态规划里其实不用存整个矩阵,按行更新的话每次只用到了上一行的值,只存最新的一行就可以),所以编程的时候只需要开一个大小为四的数组,本题还算简单,下边直接上代码:
#include<iostream>
#include<cmath>
//#include<fstream>
//#include<iomanip>
using namespace std;
int main()
{
int second;
int fenzhong;
int a;
int n=0;
int flag;
cin>>second;
fenzhong=second/60;
a=fenzhong;
int jieguo[4];
n=0;
while(fenzhong>=0)
{
if(n==0)
{
jieguo[n]=0;
}
else if(n==1)
{
jieguo[n]=1;
}
else if(n==2)
{
jieguo[n]=1;
}
else if(n==3)
{
jieguo[n]=1;
}
//数组丢弃第一个值,后边依次前移
else{
flag=(jieguo[3]+jieguo[2]+jieguo[1])%425;
jieguo[0]=jieguo[1];
jieguo[1]=jieguo[2];
jieguo[2]=jieguo[3];
jieguo[3]=flag;
}
n++;
fenzhong--;
}
if(a==0){cout<<0;}
if(a==1||a==2||a==3){cout<<1;}
if(a>3){cout<<jieguo[3]%425;}
return 0;
}
一些小点
1.关于题目限制的256MB能开多大的数组:
int=4B=32b longlongint=8B=64b
256Mb=256*1e6 b
256MB/32b=67108864(int)
256MB/64b=33554432(llint)
所以 就差不多这么大。
2.取模:
最初过程中没有取模,直接就最后的最后取模,就导致过程中数太大爆了,所以下次再遇到就……注意点吧。
3.关于时间限制:
时间限制是1000MS,据大佬说计算机一秒可以进行1e6次的操作,每个操作只有100的计算,这种比赛一般暴力递归之类的貌似大概率超时。