题解:P11376 [GESP202412 六级] 运送物资
P11376 题解
题目传送门
题意分析
题意很简单,要把
不难想到,一辆车每往
不免想到贪心。既然一辆车每往
先把所有站点排个序,然后将
AC Code
下面是本人考场代码,给大家献丑了。
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
const int N=1e5;
struct node {
int a,b;
}cara[N+5],carb[N+5];//cara存a[i]较大的车,carb存b[i]较大的车
struct point {
int p,c;
}st[N+5];//每个车站信息
int n,m,px;
int cnta=0,cntb=0;
ll ans=0;
bool cmp(node x,node y) {
return abs(x.a-x.b)<abs(y.a-y.b);
}
bool cmq(point x,point y) {
return x.p<y.p;
}
int main() {
cin>>n>>m>>px;
for(int i=1; i<=n; i++) {
cin>>st[i].p>>st[i].c;
}
sort(st+1,st+1+n,cmq);
for(int i=1; i<=m; i++) {
int x,y;
cin>>x>>y;
if(x>=y) cara[++cnta].a=x,cara[cnta].b=y;
else carb[++cntb].a=x,carb[cntb].b=y;
}
sort(cara+1,cara+1+cnta,cmp);//采用倒着排序,后面每次放完一辆车后只需cnta--便可删除这个车
sort(carb+1,carb+1+cntb,cmp);//同理
int l=1,r=n;
while(cnta>0) {
if(cnta<st[l].c) {//小心下表越界
while(cnta>0) {
ans=ans+2ll*cara[cnta].a*st[l].p+2ll*cara[cnta].b*(px-st[l].p);
cnta--;//放完这辆车了,删掉
}
} else {
for(int i=1; i<=st[l].c; i++) {
ans=ans+2ll*cara[cnta].a*st[l].p+2ll*cara[cnta].b*(px-st[l].p);//计算答案
cnta--;//放完这辆车了,删掉
}
l++;//下一车站
}
}
while(cntb>0) {
if(cntb<st[r].c) {//小心下表越界
while(cntb>0) {
ans=ans+2ll*carb[cntb].a*st[r].p+2ll*carb[cntb].b*(px-st[r].p);
cntb--;//放完这辆车了,删掉
}
} else {
for(int i=1; i<=st[r].c; i++) {
ans=ans+2ll*carb[cntb].a*st[r].p+2ll*carb[cntb].b*(px-st[r].p);//计算答案
cntb--;//放完这辆车了,删掉
}
r--;//下一车站
}
}
cout<<ans;//输出
return 0;
}