noip1998火车过站 (斐波那契数列)

A1117. 火车过站
时间限制: 1.0s   内存限制: 256.0MB  
总提交次数: 861   AC次数: 264   平均分: 39.59
将本题分享到:
       
   
试题来源
  NOIP1998 提高组
问题描述
  火车从始发站(称为第1站)开出,在始发站上车的人数为a,然后到达第2站,在第2站有人上、下车,但上、下车的人数相同,因此在第2站开出时(即在到达第3站之前)车上的人数保持为a人。从第3站起(包括第3站)上、下车的人数有一定规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第n-1站),都满足此规律。现给出的条件是:共有N个车站,始发站上车的人数为a,最后一站下车的人数是m(全部下车)。试问x站开出时车上的人数是多少?
输入格式
  输入包含一行, 有四个正整数:a(a<=100),n(n<=20),m(m<=10000)和x(x<=19)
输出格式
  输出为一个整数,为x站开出时车上的人数。


解析:我们用up[i]表示在第 i 站上车的人数,add[i]表示在第 i 站的时候增加的人数,sum[i]表示从第 i 站出发时的人数,b[i]表示斐波那契数列的第 i 项,并假设第二站上车人数为k,则有:

由题意可得关系式:up[i]=up[i-1]+up[i-2](斐波那契数列的递推公式)

                                add[i]=up[i-2]

up[1]=1*a+0*k             add[1]=1*a+0*k             sum[1]=1*a+0*k

up[2]=0*a+1*k             add[2]=0*a+0*k             sum[2]=1*a+0*k

up[3]=1*a+1*k             add[3]=1*a+0*k             sum[3]=2*a+0*k

up[4]=1*a+2*k             add[4]=0*a+1*k             sum[4]=2*a+1*k

up[5]=2*a+3*k             add[5]=1*a+1*k             sum[5]=3*a+2*k

up[6]=3*a+5*k             add[6]=1*a+2*k             sum[6]=4*a+4*k

up[7]=5*a+8*k             add[7]=2*a+3*k             sum[7]=6*a+7*y


由上述推理可得:sum[i]=(b[0]+b[1]+b[2]+...+b[i-4]+2)*a+(b[0]+b[1]+....+b[i-3])*k

根据斐波那契数列的性质:b[0]+b[1]+...+b[i]=b[i+2]-1

sum[i]=(b[i-2]+1)*a+(b[i-1]-1)*k;


综上:m=(b[n-2]+1)*a+(b[n-1]-1)*k (根据此式,算出 k 的值)

          sum[x]=(b[x-2]+1)*a+(b[x-1]-1)*k (得到答案)

观察代码,我们会发现,在n<=4时,求 k 的除法会出现问题(并且由上可知,在n<=4时,答案是与 k 无关的),所以我们将k的值初始化为 0 ;

                                       当x==1时,我们输出答案部分也会出错,所以x==1的情况要特判。

代码:

#include <cstdio>
using namespace std;

int b[20]={0,1,1};

int main()
{
  int a,n,m,x,i,k=0;
  scanf("%d%d%d%d",&a,&n,&m,&x);
  if(x==1){printf("%d",a);return 0;}
  for(i=3;i<20;i++)b[i]=b[i-1]+b[i-2];
  if(n>4)k=(m-(b[n-3]+1)*a)/(b[n-2]-1);
  printf("%d",(b[x-1]-1)*k+(b[x-2]+1)*a);
  return 0;
} 



    • 1
      点赞
    • 3
      收藏
      觉得还不错? 一键收藏
    • 0
      评论

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值