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