Codevs 2287 火车站

来源:互联网 发布:广州恒大淘宝足球俱乐部 编辑:程序博客网 时间:2024/04/28 01:43

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的系数;
那么

站点 1 2 3 4 5 6 7 上车f a x a+x a+2x 2a+3x 3a+5x 5a+8x 下车d 0 x x a+x a+2x 2a+3x 3a+5x 人数s a a 2a 2a+x 3a+2x 4a+3x 6a+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

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

车站 净人数叠加 1 n[1]*a+m[1]*x-d[1] 2 n[2]*a+m[2]*x-d[2] 3 n[3]*a+m[3]*x-d[3] 4 n[4]*a+m[4]*x-d[4] 5 n[5]*a+m[5]*x-d[5] … … i n[i]*a+m[i]*x-d[i] 3~i n[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数列的求和公式

番外

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


雪花的快乐

     ——徐志摩

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

0 0