其他分享
首页 > 其他分享> > P1011 [NOIP1998 提高组] 车站

P1011 [NOIP1998 提高组] 车站

作者:互联网

P1011 [NOIP1998 提高组] 车站

【题目描述】

火车从始发站(称为第 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

数据范围:1≤a≤20,1≤x≤n≤20,1≤m≤2e4。

【题解】

读题:已经知道 a, n, m, x,但是第二站上下车人数不定,假设第二站上车人数为 b ,列出下表;

车站编号 1 2 3 4 5 6 7 x n-1 n
上车人数 up[i] a b a+b a+2b 2a+3b 3a+5b 5a+8b 0
下车人数 down[i] 0 b a b a+b 3b 3a+5b m
两者差值 dis[i] a 0 b a+b a+2b 2a+3b 3a+5b
发车人数 f[i] a a 2a 2a+b 3a+2b 4a+4b 6a+7b m

两种方式第一种,暴力枚举 b,理论上 b的取值范围为 [0,inf],这种方法有点取巧和作弊了。

#include<bits/stdc++.h>
using namespace std;
const int N=2e4+1;
int up[N], down[N], f[N];
int main_ac(){
//    freopen("data.in", "r", stdin);
    int a,n,m,x; cin>>a>>n>>m>>x;
    up[1]=a; down[1]=0;
    for(int b=0; ; b++){
        up[2]=down[2]=b;
        for(int i=3; i<=n; i++){
            up[i]=up[i-1]+up[i-2];
            down[i]=up[i-1];
        }
        f[1]=a;
        for(int i=2; i<=n; i++){
            f[i]=f[i-1] + up[i]-down[i];
        }
        if(f[n-1]==m) {
            cout<<f[x]; break;
        }
    }
    return 0;
}

第二种,找规律,解出 b

发车人数 f[i]:a  a  2a  2a+b  3a+2b  4a+4b  6a+7b  9a+12b  14a+20b ....   m
提取 f[i]的系数:10 10 20 21 32 44 67 9,12 14,20 ...
找到规律,当:
a 的系数,A[i]=A[i-1]+A[i-2]-1  //此处归纳得出,还需证明
b 的系数,B[i]=B[i-1]+B[i-2]+1

所以 x 站台的发车人数 f[x]=A[x]*a+B[x]*b
n-1 站台的发车人数 f[n-1]=A[n-1]*a+B[n-1]*b=m
解出 b=(m-A[n-1]*a)/B[n-1];
从而得到 f[x]
#include<bits/stdc++.h>
using namespace std;
const int N=2e4+1;
int A[N], B[N], F[N];
int main(){
//    freopen("data.in", "r", stdin);
    int a,n,m,x; cin>>a>>n>>m>>x;
    A[1]=A[2]=1, A[3]=2;
    B[1]=B[2]=B[3]=0;
    for(int i=4; i<=n-1; i++){
        A[i]=A[i-1]+A[i-2]-1;//此处归纳得出,还需证明
        B[i]=B[i-1]+B[i-2]+1;
    }
    int b=(m-A[n-1]*a)/B[n-1];//推导公式
    F[x]=A[x]*a+B[x]*b;
    cout<<F[x];
    return 0;
}

标签:下车,int,车站,P1011,2a,NOIP1998,上车,人数,3a
来源: https://www.cnblogs.com/hellohebin/p/15253948.html