有一说一,对于语言理解能力有问题的本菜鸡来说,理解题意就花了不少时间(手动秃头)。
目录
1、题意分析
有n个车站,uim这位悲惨的社畜需要在各个不同的地点(因为不能直达,所以uim一次行动可能要经过多个车站)之间辗转m次。而每段铁路的付费方式分为两种,简单地说就是,不办卡和办卡两种。而其中办卡又需要先交工费c,并且工费不退回,也不能当成卡中余额用来搭车(说白了,就付了几百块,办了张空卡)。当然当然,只让你办空卡,不给你福利是不会有人要去搭车滴。所以,铁路公司就决定让办卡的乘客可以少付一部分车费,也就是只用付b。b一定比直接买票的价格a便宜。
现在,我们需要做的就是,帮助uim算出怎么样搭车可以花费最少的钱(一定是公司不给报销,老板真是太可恶了,可怜的uim),并且输出最少的价钱。
2、解题思路
因为时间限制为一秒,所以暴力解题肯定是不行滴。题的标签也已经提到了会使用前缀和。然后进一步的思考了一下发现,记录每一段铁路走过的次数,可以使用差分来计算。也就因此进一步,减少了运行时间啦。(好家伙,我发现我的代码里压根儿没有前缀和,救命。算了不管,反正题目的便签上有)。
其实,该说的注释里也写的差不多了,我就不再多说了。大家直接看代码吧。
3、AC代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll num [100010];//每段路去过的次数
int main () {
ll N , M , p;//总站台数 会去的站台个数 记录当前所在站台号
ll m , t;//前一站台的号码 比较并交换站台序号的中间量
scanf("%lld %lld" , &N , &M);
for(ll i = 1 ; i <= M ; i ++) {
scanf("%lld" , &p);//输入站台次序
ll k = p;//方便正序记录下所到的站台序号
if(i == 1){
m = p;
continue;
}
if(m > p){
t = m;
m = k;
k = t;
}//如果后输入的站台号小
num[m] += 1;
num[k] -= 1;
m = p;//记录每段路需要经过的次数
}
ll d[100010] , single , car , cost = 0;
//到过每段路的次数 买单程票需要的钱 办卡需要的钱 总钱数
ll a , b , c;//该站 单程票价 IC卡票价 卡费
for(ll i = 1 ; i < N ; i ++){//每段路的价钱
scanf("%lld %lld %lld" , &a , &b , &c);
d[i] = d[i-1] + num[i];
single = a * d[i];
car = b * d[i] + c;
if(single <= car)cost += single;
else cost += car;
}
printf("%lld" , cost);
return 0;
}
注:在上一篇博客里面有写,为什么不使用cin和cout,这里就不多说了。友友们,加油冲冲冲!