题目描述
火车从始发站(称为第 1 站)开出,在始发站上车的人数为 a,然后到达第 2 站,在第 2 站有人上、下车,但上、下车的人数相同,因此在第 2 站开出时(即在到达第 3 站之前)车上的人数保持为 a 人。从第 3 站起(包括第 3 站)上、下车的人数有一定规律:上车的人数都是前两站上车人数之和,而下车人数等于上一站上车人数,一直到终点站的前一站(第 n−1 站),都满足此规律。现给出的条件是:共有 n 个车站,始发站上车的人数为 a,最后一站下车的人数是 m(全部下车)。试问 x 站开出时车上的人数是多少?
输入格式
输入只有一行四个整数,分别表示始发站上车人数 𝑎a,车站数 𝑛n,终点站下车人数 𝑚m 和所求的站点编号 x。
输出格式
输出一行一个整数表示答案:从 x 站开出时车上的人数。
今天刷了一道很有意思的题目,刚开始做的时候我以为这是一个非常简单的题,想着直接秒了,后面才发现没那么简单,哈哈,小瞧这个题了
来瞪一会,看能不能发现规律
如果只看人数那行,肯定啥也发现不了,我们不妨看实际增量,你就会发现1 ,2不看,3 ,4是初值,后面的都是f(n) = f(n-1) + f(n-2),也就是从3,4项开始变成斐波那契数列了,那就简单了,实际增量的前缀和数组找到了,记录一下有多少a有多少x然后利用最后一项题目给出的值求出x,然后在根据实际增量的前缀和数组创出人数数组,返回题目要的那个车站值即可
代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 25;
int b[N],arr[N] = {0};
string s[N];
int a,n,m,k,i = 0,j = 0;
int main()
{
cin >> a >> n >> m >> k;
if(n <= 2){
cout << a << endl;
return 0;
}
s[1] = "a",s[2] = "",s[3] = "a",s[4] = "x";
for(int i=5;i<n;i++){
s[i] = s[i-1] + s[i-2];
}
string ss = "";
for(int i=1;i<n;i++){
ss += s[i];
}
// cout << ss << endl;
int u = 0,v = 0,l = ss.size();
for(int i=0;i<l;i++){
if(ss[i] == 'a') u ++;
else v ++;
}
// cout << u << " " << v << endl;
int x = (m - u * a) / v;
// cout << x << endl;
b[1] = a,b[2] = 0,b[3] = a,b[4] = x;
for(int i=5;i<n;i++){
b[i] = b[i-1] + b[i-2];
}
arr[1] = a;
for(int i=2;i<=n;i++){
arr[i] += b[i] + arr[i-1];
}
// for(int i=1;i<=n;i++){
// cout << arr[i] << " ";
// }
cout << arr[k] << endl;
return 0;
}
看这注释你就可以想象我debug有多久了,哈哈
加油