首页 > 代码库 > 洛谷P3406 海底高铁
洛谷P3406 海底高铁
题目背景
大东亚海底隧道连接着厦门、新北、博艾、那霸、鹿儿岛等城市,横穿东海,耗资1000亿博艾元,历时15年,于公元2058年建成。凭借该隧道,从厦门可以乘坐火车直达台湾、博艾和日本,全程只需要4个小时。
题目描述
该铁路经过N个城市,每个城市都有一个站。不过,由于各个城市之间不能协调好,于是乘车每经过两个相邻的 城市之间(方向不限),必须单独购买这一小段的车票。第i段铁路连接了城市i和城市i+1(1<=i<N)。如果搭乘的比较远,需要购买多张 车票。第i段铁路购买纸质单程票需要Ai博艾元。
虽然一些事情没有协调好,各段铁路公司也为了方便乘客,推出了IC卡。对于第i段铁路,需要花Ci博艾元的工本费购买一张IC卡,然后乘坐这段铁路 一次就只要扣Bi(Bi<Ai)元。IC卡可以提前购买,有钱就可以从网上买得到,而不需要亲自去对应的城市购买。工本费不能退,也不能购买车票。 每张卡都可以充值任意数额。对于第i段铁路的IC卡,无法乘坐别的铁路的车。
Uim现在需要出差,要去M个城市,从城市P1出发分别按照P1,P2,P3...PM的顺序访问各个城市,可能会多次访问一个城市,且相邻访问的城市位置不一定相邻,而且不会是同一个城市。
现在他希望知道,出差结束后,至少会花掉多少的钱,包括购买纸质车票、买卡和充值的总费用。
输入输出格式
输入格式:第一行两个整数,N,M。
接下来一行,M个数字,表示Pi
接下来N-1行,表示第i段铁路的Ai,Bi,Ci
输出格式:一个整数,表示最少花费
输入输出样例
9 103 1 4 1 5 9 2 6 5 3200 100 50300 299 100500 200 500345 234 123100 50 100600 100 1450 400 802 1 10
6394
说明
2到3以及8到9买票,其余买卡。
对于30%数据 M=2
对于另外30%数据 N<=1000 ,M<=1000
对于100%的数据 M,N<=100000,Ai,Bi,Ci<=100000
用前缀和数组算出每条路的经过次数,最后扫描每条路,决定买不买卡。
代码第35行的地方,我第一次写了 min( (long long)a*p, (long long)c+b*p) ,a b c都是int。 问题很明显:b*p花式越界。
嗨呀好气呀
1 /*By SilverN*/ 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<algorithm> 7 #define LL long long 8 using namespace std; 9 int read(){10 int x=0,f=1;char ch=getchar();11 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}12 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}13 return x*f;14 }15 const int mxn=240000;16 int n,m;17 int smm[mxn];18 LL a,b,c;19 void clc(int a,int b){20 if(a>b)swap(a,b);21 smm[a]++;smm[b]--;22 return;23 }24 int main(){25 n=read();m=read();26 int i,j;27 int last,p;28 last=read();29 for(i=2;i<=m;i++){p=read();clc(last,p);last=p;}30 p=0;31 long long ans=0;32 for(i=1;i<n;i++){33 p+=smm[i];34 a=read();b=read();c=read();35 long long tmp=min(a*p,b*p+c);36 ans+=tmp;37 }38 cout<<ans<<endl;39 return 0;40 }
洛谷P3406 海底高铁