火车从始发站(称为第1站)开出,在始发站上车的人数为a,然后到达第2站,在第2站有人上、下车,但上、下车的人数相同,因此在第2站开出时(即在到达第3站之前)车上的人数保持为a人。从第3站起(包括第3站)上、下车的人数有一定规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第n−1站),都满足此规律。现给出的条件是:共有N个车站,始发站上车的人数为a,最后一站下车的人数是m(全部下车)。试问x站开出时车上的人数是多少?
a(≤20),n(≤20),m(≤2000),和x(≤20),
对于该题,我们并不知道从第二站开始上车的人数。所以不妨设为b。 则我们可以得到以下列表
乍一看,好像没有什么规律。但如果我们将其过程种上下车的人数也表现出来 就有下列表格 首先,注意“上a”与“上b”的表格,从第3站开始,系数呈现为斐波那契数列的特点; 其次,注意“下a"与”下b"的表格,从第5站开始,系数呈现为斐波那契数列的特点。 这样本题的关键点就被解决了。
a与b的系数为上车系数减去下车系数,得车上人数。
#include <iostream> #define N 21 using namespace std; int a1[N],b1[N],a2[N],b2[N],s[N],h[N]; //a1表示上a,a2表示下a, b1表示上b, b2表示下b, s存储a的系数,h存储b的系数 int main() { int i; int a,n,m,x,b,ans; cin>>a>>n>>m>>x; int sum=0,thm=0,sum1=0,thm1=0; a1[1]=1;a1[2]=0;b1[1]=0;b1[2]=1; for (i=3; i<=N; i++) { a1[i]=a1[i-1]+a1[i-2]; b1[i]=b1[i-1]+b1[i-2]; } //将a1与b1的元素确定 a2[1]=0;a2[2]=0;a2[3]=0;a2[4]=1; b2[1]=0;b2[2]=1;b2[3]=1;b2[4]=1; for (i=5; i<=N; i++) { a2[i]=a2[i-1]+a2[i-2]; b2[i]=b2[i-1]+b2[i-2]; } //将a2与b2的元素确定 for (i=1; i<=n; i++) { s[i]=a1[i]-a2[i]; h[i]=b1[i]-b2[i]; sum+=s[i]; thm+=h[i]; } //将s与h的元素确定,sum与thm,分别表示第n站a与b的系数 b=(m-sum*a)/thm; //用n-1站的人数求出b if (x==n) { cout<<0<<endl; return 0; } //终点站全部下车,车上人数为0 if (x==1 || x==2) { cout<<a<<endl; return 0; } if (x==3) { cout<<2*a<<endl; return 0; } else if (x>=4) { for (i=1; i<=x; i++) { sum1+=s[i]; thm1+=h[i]; } ans=sum1*a+thm1*b; cout<<ans<<endl; //计算并输出第x站的人数 return 0; } }当然,该题的参考数最多只有20个,数目较少。也可以暴力解决——直接打表。
#include <iostream> #define N 21 using namespace std; int a1[N], b1[N]; int main() { a1[N]={0,1,1,2,2,3,4,6,9,14,22,35,56,90,145,234,378,611,988,1598,2585}; //储存第i站a的系数 b1[N]={0,0,0,0,1,2,4,7,12,20,33,54,88,143,232,376,609,986,1596,2583,4180}; //储存第i站b的系数 int a,n,m,x,b,ans; cin>>a>>n>>m>>x; b=(m-a1[n-1]*a)/b1[n-1]; //求b的值 ans=a[x]*a + b[x]*b; cout<<ans<<endl; return 0; }十分简单粗暴,但对于数量较多时。。。自行领会。