Appoint description:
Description
【问题描述】
公共汽车从始发站(称为第1站)开出,在始发站上车的人数为a,然后到达第2站,在第2站有人上、下车,但上、下车的人数相同,因此在第2站开出时(即在到达第3站之前)车上的人数保持为a人。从第3站起(包括第3站)上、下车的人数有一定的规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第n-1站),都满足此规律。现给出的条件是:共有n个车站,始发站上车的人数为a,最后一站下车的人数是m(全部下车)。试问从x站开出时车上的人数是多少?
【输入】
只有一行,四个整数a,n,m和x
【输出】
x站开出时车上的人数
【样例输入】
5 7 32 4
【样例输出】
13
思路:
这题其实就是斐波那契数列的变形,这题因为一些细节
而错了一次。
这题其实可以设开始是a人,第二次上了x人也下了x人,所以要用
最后到站下了的m人去求x。
1 2 3 4 5 6 7 8 ......
a a 2a 2a+x 3a+2x 4a+4x 6a+7x 9a+12x ......
所以可以看出下面的规律。
fa[n] = fa[n-1] + fa[n-2] - 1;//a的系数
fx[n] = fx[n-1] + fx[n-2] + 1;//x的系数
AC代码:
#include<iostream> #include<algorithm> #include<cstring> #include<string> #include<cstdio> #include<cmath> #include<ctime> #include<cstdlib> #include<queue> #include<vector> #include<set> using namespace std; const int T=1550000; #define inf 0x3f3f3f3fL typedef long long ll; ll v[T],w[T]; int main() { #ifdef zsc freopen("input.txt","r",stdin); #endif int a,n,m,x,i; v[1]=1,v[2]=1,v[3]=2,v[4]=2; w[1]=0,w[2]=0,w[3]=0,w[4]=1; for(i=5;i<T;++i){ v[i] = v[i-1]+v[i-2]-1; w[i] = w[i-1]+w[i-2]+1; } while(~scanf("%d%d%d%d",&a,&n,&m,&x)) { ll tmp; ll sum = 0; if(x<3){ printf("%d\n",a); continue; } tmp = (m - v[n-1]*a)/w[n-1]; sum = v[x]*a + tmp*w[x]; printf("%lld\n",sum); } return 0; }