Codevs 2287 火车站

Codevs 2287 火车站问题解析与解决方案
博客详细分析了Codevs 2287 火车站问题,其中火车上人数遵循斐波那契数列规律。通过两种不同的推导方法,得出计算车上人数的公式,并提供了代码实现。测试结果显示代码正确性。

Codevs 2287 火车站


题目描述 Description

火车从始发站(称为第1站)开出,在始发站上车的人数为a,然后到达第2站,在第2站有人上、下车,但上、下车的人数相同,因此在第2站开出时(即在到达第3站之前)车上的人数保持为a人。从第3站起(包括第3站)上、下车的人数有一定的规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第n-1站),都满足此规律。现给出的条件是:共有N个车站,始发站上车的人数为a,最后一站下车的人数是m(全部下车)。试问从x站开出时车上的人数是多少?若无解输出“No answer.”(所有数据均在longint范围内)


输入输出


输入描述 Input Description

a,n,m和x

输出描述 Output Description

x站开出时车上的人数


样例


样例输入 Sample Input

1 6 7 3

样例输出 Sample Output

2


数据范围及提示 Data Size & Hint

分析

根据题意,我们可以设m[i]为a的系数,n[ i]为b的系数;
那么

站点1234567
上车faxa+xa+2x2a+3x3a+5x5a+8x
下车d0xxa+xa+2x2a+3x3a+5x
人数saa2a2a+x3a+2x4a+3x6a+6x

根据题意(3站后的上车人数等于前两站的上车人数和的定义)我们可以得出上车人数显然为斐波那契数列;

fi]:=f[i-1]+f[i-2];
f[i]:=m[i]*a+n[i]*x;
d[i]:=f[i-1];
s[i]:=s[i-1]+f[i]-d[i]
s[i]:=s[i-1]+f[i-2];
s[i]:=s[i-1]+m[i-2]*a+n[i-2]*x;
接下来 有两种推导s[i]的办法,表示本人较笨。。。选用了一种较笨的方法。


推导


方法1

分析即可的,车上的人数即为一开始的人数加上每次的净上车量(上车人数-下车人数);那么写开叠加如下

车站净人数叠加
1n[1]*a+m[1]*x-d[1]
2n[2]*a+m[2]*x-d[2]
3n[3]*a+m[3]*x-d[3]
4n[4]*a+m[4]*x-d[4]
5n[5]*a+m[5]*x-d[5]
in[i]*a+m[i]*x-d[i]
3~in[i]*a+m[i]*x-d[3]

然后由题中的关系可以得出
n[i]*a+m[i]*x=d[i] (下车人数等于前一站的上车人数,从第三天开始,i>=3)
边界 n[1]:=1; n[2]:=0; n[3]:=1;
m[1]:=0;m[2]:=1;m[3]:=1;
d[1]:=0; d[2]:=x d[3]:=x
然后对表格中的数据叠加


即可得到

s[i]:
=n[1]*a+m1[1]*x-d[1]+n[2]*a+m[2]*x-d[2]+n[i]*a+m[i]*x-d[3]
=a+x-x+n[i]*a+m[i]*x-x
=(n[i]+1)*a+(m[i]-1)x


所以我们就得到了车上人数的计算公式。
有题目中的n站时所有人下车m人得出n-1站有m人。所以

m=s[i-1]=(n[i-1]+1)*a+(m[i-1]-1)*x
x=(m-(n[i-1]+1)*a) div (m[i-1]-1);
要求((m-(n[i-1]+1)*a) mod (m[i-1]-1))=0
否则无解(人不能有小数个);


方法二

由如下式变换

fi]:=f[i-1]+f[i-2];
f[i]:=m[i]*a+n[i]*x;
d[i]:=f[i-1];
s[i]:=s[i-1]+f[i]-d[i]
s[i]:=s[i-1]+f[i-2];
s[i]-s[i-1]:=f[i-2]

右侧很熟悉,进行叠加
如下(由于i-2>=2所以,i>=4时进行叠加)

s[n]-s[n-1]f[n-2]
s[i]-s[i-1]f[i-2]
s[i-1]-s[i-2]f[i-3]
s[i-2]-s[i-3]f[i-4]
s[i-3]-s[i-4]f[i-5]
s[i-4]-s[i-5]f[i-6]
s[6]-s[5]f[4]
s[5]-s[4]f[3]
s[4]-s[3]f[2]

叠加结果如下

s[i]-s[3]:=(f[2]+f[3]+…+f[i-2])
s[i]-s[3]:=(n[2]+n[3]+…+n[i-2])*a+(m[2]+m[3]+m[4]+…+m[i-2])*b
结合斐波那契数列求和公式
如下
f[n]:=f[n-1]+f[n-2]

f[n-2]:=f[n]-f[n-1];
f[n-3]:=f[n-1]-f[n-2];
….
f[3]:=f[2]-f[1]
f[3]+…+f[n-2]:=f[n]-f[1];
f[1]+f[2]
+f[3]+…+f[n-2]:=f[n]+f[2];
S[n]:=s[n+2]+f[2];
上述式子可化为
s[i]:=(m[i]-1)*a+(n[i]-1)*x+2a
s[i]:=(m[i]+1)*a+(n[i]-1)*x

两种方法推导完毕。
接下来就是代码实现即可


代码如下

program p2287;
var k,n,m,a,x,i:longint;
    f:array[1..100000,1..2] of longint;

begin
 readln(a,n,m,x);
 f[1,1]:=1;  f[1,2]:=0;
 f[2,1]:=0;  f[2,2]:=1;
 f[3,1]:=1;  f[3,2]:=1;
 for i:=4 to n do
  begin
   f[i,1]:=f[i-1,1]+f[i-2,1];
   f[i,2]:=f[i-1,2]+f[i-2,2];
  end;
 if ((m-(f[n-1,1]+1)*a)mod (f[n-1,2]-1))<>0 then write('No answer.')
  else
   begin
    k:=(m-(f[n-1,1]+1)*a) div (f[n-1,2]-1);
    write((f[x,1]+1)*a+(f[x,2]-1)*k);
   end;
end.

测试结果

运行结果
测试点#work2_2.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#work2_3.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#work2_4.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#work2_5.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms


阅读资料

关于Fibonacci数列的求和公式

番外

这里写图片描述这里写图片描述


雪花的快乐

     ——徐志摩

假如我是一朵雪花,
翩翩的在半空里潇洒,
我一定认清我的方向——
飞飏,飞飏,飞飏——
这地面上有我的方向。
不去那冷寞的幽谷,
不去那凄清的山麓,
也不上荒街去惆怅——
飞飏,飞飏,飞飏——
你看,我有我的方向!
在半空里娟娟地飞舞,
认明了那清幽的住处,
等着她来花园里探望——
飞飏,飞飏,飞飏——
啊,她身上有朱砂梅的清香!
那时我凭借我的身轻,
盈盈地,沾住了她的衣襟,
贴近她柔波似的心胸——
消溶,消溶,消溶——
溶入了她柔波似的心胸

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值