INPUT
3 100
-10 50
10 175
25 20
OUTPUT
90
INPUT
5 3
-1002 800
-1001 800
-1000 800
-999 800
-998 800
OUTPUT
2668000
题意:有n个需要送信的点,每次可以送m封信,接下来n组,x(地点坐标),y(该地点需要送的信的数量),需要回到原点,问最短走的路程是多少。
思路:按照地点先排好序,计算出坐标轴右侧的,原则是先送最远的,顺带往坐标轴中间凑,能够顺带送的每次都更新。具体看代码。
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const int mod=1e9+10;
const int M= 1e4 + 10;
struct A
{
int p,q;
}a[M];
bool cmp(A pp,A qq)
{
if(pp.p == qq.p)
return pp.q<qq.q;
return pp.p<qq.p;
}
int main()
{
int n,m,i,j,sum=0;
cin>>n>>m;
for(i=0;i<n;i++)
{
cin>>a[i].p>>a[i].q;
if(a[i].p >= 0)
sum++;
}
sort(a,a+n,cmp);
ll ans=0,x,y;
for(i=n-1;i>= n-sum;i--)//计算坐标轴右侧的
{
x=a[i].q/m;
y=a[i].q%m;
ans+=x*a[i].p*2;
if(y!=0)
{
ans+=a[i].p*2;//多出来的也按照路程长的来计算
y=m-y;
for(j=i-1;j>=n-sum;j--)//更新前面可以顺便送的
{
if(a[j].q>=y)
{
a[j].q-=y;
y=0;
break;
}
else//继续向前更新
{
y-=a[j].q;
a[j].q=0;
}
}
}
}
for(i=0;i<= n-sum-1;i++)//计算坐标轴左侧的
{
x=a[i].q/m;
y=a[i].q%m;
ans+=x*(-a[i].p)*2;
if(y!=0)
{
ans+=(-a[i].p)*2;
y=m-y;
for(j=i+1;j<=n-sum-1;j++)
{
if(a[j].q>=y)
{
a[j].q-=y;
y=0;
break;
}
else
{
y-=a[j].q;
a[j].q=0;
}
}
}
}
cout<<ans<<endl;
return 0;
}
可以做做这个类似的题目 Postman