2023 CCF CSP-J 第二轮认证第二题 公路(rode)
题目:小苞准备开着车沿着公路自驾。
公路上一共有n个站点,编号为从1到n。其中站点i与站点i+1的距离为w公
公路上每个站点都可以加油,编号为i 的站点-一升油的价格为q元,且每个站点
只出售整数升的油。
小苞想从站点1开车到站点n。一开始小苞在站点 1且车的油箱是空的。已知车的
油箱足够大,可以装下任意多的油,且每升油可以让车前进d公里。问小苞从站点1开
到站点n,至少要花多少钱加油?
[输入格式]
从文件road. in中读入数据。
输入的第–行包含两个正整数
和d,分别表示公路上站点的数量和车每升油可以
前进的距离。
.分别表示站点间的距离。
输入的第二行包
含n-1个正整数y分别表示站点间的距离。
输入的第二行包含n个正整数a1…分别表示在不同站点加油的价格。
[输出格式]
输出到文件road.out中。
输出一行,仅包含–个正整数,表示从站点1开到站点n,小苞至少要花多少钱加
[样例输入] .
54
10101010
98965
[样例输出]
79
样例分析:第一站买3升油,花费27元,第二站买 5升油,花费40元,第四站买2升油,花费12元总花费79元;
输入两个整形变量,d存储一升油可以行驶的距离,n存储总站数;两个数组,s[]装每相邻两个站台之间的距离,m[]装各个站台的油价。
distance即行驶的总距离,money是花钱总数,oil记录加油总量,bottle记录上次加油时的加油总量,oil-bottle就是在该站台加的油数,即money+=(oil-bottle)*m[i];
代码解读:在函数中,我们用一个while循环进行运算,循环条件为i!=n(或i<n),即循环n次。 在函数中,i代表的是车要加油的站点,m[i]即所在站点的油价,j代表的是在这个站点加完油后到下一个要加油的站点途中行驶过的站点,j每次循环加一,循环条件为行驶到的站点的油价小于此站点的油价,未到达时每经过一个站点就让distance+=s[j],如果该站点行驶到了比此站点油价更低的站点,就进行结算。 结算:当要行驶的总路程大于总油数乘以一升油可行驶的距离时,总油数oil++,当油箱中的油可行驶的距离大于要行驶的距离时,在此站点加的油为oil-bottle,在此站点花的钱即(oil-bottle)*m[i];结算完后让买油的站点i变为油价更低的站点j,继续下一次循环直到到达了最后一个站点(i==n);
#include <iostream>
#include <cmath>
using namespace std;
void road(int s[],int m[],int d,int n){
int i=1,j=1,distance=0,money=0,oil=0,bottle=0;
while(i!=n){
bottle=oil;
while(m[i]<=m[j]){
distance+=s[j];
while(oil*d<distance)
oil++;
j++;
if(j==n)break;
}
money+=(oil-bottle)*m[i];
i=j;
}
cout<<"需要最少的钱为"<< money;
}
int main(){
int n,d;
cout<<"请输入站点数"<<endl;
cin>>n;
cout<<"请输入每升油能走的距离"<<endl;
cin>>d;
int s[n],m[n];
cout<<"请输入站点之间距离数"<<endl;
for(int i=1;i<n;i++)cin>>s[i];
cout<<"请输入每个站点的油价"<<endl;
for(int i=1;i<=n;i++)cin>>m[i];
road(s,m,d,n);
}
如果有更简便的方法可以告诉我。