题目描述
火车从始发站(称为第 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 人,下车 0 人,所以净上车人数(上车的人数 - 下车的人数)为 a
-
第二站上下车人数相等,假设上、下车人数为 b 人,所以净上车人数为 0
-
第三站上车人数等于前面两站上车人数之和,下车人数为前一站的上车人数,所以第三站上车人数为 a+b,下车人数为 b,所以净上车人数为 a
-
第四站上车人数为第二站和第三站上车人数之和,下车人数是第三站上车人数,上车人数 a+2b,下车人数 a+b,所以净上车人数为 b
-
第五站上车人数为第三站和第四站上车人数之和,下车人数是第四站上车人数,上车人数 2a+3b,下车人数 a+2b,所以净上车人数为 a+b
-
以此类推,第六站净上车人数为 a+2b,第七站净上车人数为 2a+3b......
将各个站的净上车人数做成表格更加清晰明了 ,我们可以发现某一站的净上车人数等于前面两站净上车人数之和,类似斐波那契数列。但又不是完全一样,比如第四站的净上车人数就不等于第二站和第三站的净上车人数之和。所以我们还应该做些许改动,让其与斐波那契数列有着相同的规律
站数 | 第一站 | 第二站 | 第三站 | 第四站 | 第五站 | 第六站 | 第七站 |
净上车人数 | a | 0 | a | b | a+b | a+2b | 2a+3b |
我们将净上车人数分开来看,如果净上车人数里面有 a,就放入数列 a,没有就把 0 放入数列 a 中,如果净上车人数里面有 b,就放入数列 b,没有就把 0 放入数列 b 中,然后再观察它们的变化
站数 | 第一站 | 第二站 | 第三站 | 第四站 | 第五站 | 第六站 | 第七站 |
数列 a | a | 0 | a | 0 | a | a | 2a |
数列 b | 0 | 0 | 0 | b | b | 2b | 3b |
我们可以发现数列 a 与数列 b 在前四站不符合斐波那契数列的规律,而从第五站开始,当前站的数列 a 与数列 b 都为前面两站之和,所以可以使用递归来解决此问题,对数列 a 与数列 b 都使用递归,如果传进来的参数小于等于4,就返回它们的值,如果大于4,就返回参数-1的值 + 参数-2的值
代码
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
int n = sc.nextInt();
int m = sc.nextInt();
int x = sc.nextInt();
int num1 = 0; //储存数列 a 的前n-1 项和
int num2 = 0; //储存数列 b 的前n-1 项和
int x1 = 0, x2 = 0; //记录第 x 站时,车上的人数
for (int i = 1; i < n; i++) {
num1 += f1(i);
num2 += f2(i);
if (i == x) {
x1 = num1;
x2 = num2;
}
}
int b = (m - num1 * a) / num2; //求出第二站上车的人数 b
System.out.println(x1 * a + x2 * b);
}
public static int f1(int n) { //数列 a 的递归
if (n == 1 || n == 3) {
return 1;
}
if (n == 2 || n == 4) {
return 0;
}
return f1(n - 1) + f1(n - 2);
}
public static int f2(int m) {
if (m == 1 || m == 2 || m == 3) { //数列 b 的递归
return 0;
}
if (m == 4) {
return 1;
}
return f2(m - 1) + f2(m - 2);
}
}