题目链接
题目大意:有一个邮差,邮局在坐标0点,接下来有n次请求,每次请求包括一个坐标点和要送的信件数目,邮差所能带的信件数目最大为k,每次送完后要回到0点,最后也要回到0点,求运送完成的最小时间。
贪心,先走最远的,一开始写的暴力跑,TLE了,可以选择把最远的可以优化的容量都累计到相邻的请求中去,这样只需要跑一遍for循环即可。
AC代码:
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
struct node
{
long long
x,m;
} a[2000],b[2000];
int cmp(node a,node b)
{
return a.x<b.x;
}
int cmp2(node a,node b)
{
return a.x>b.x;
}
int main()
{
int n,k;
cin>>n>>k;
node tmp;
int top1 =0 ;
int top2 =0 ;
for(int i=1; i<=n; i++)
{
scanf("%lld%lld",&tmp.x,&tmp.m);
if(tmp.x<0)a[++top1] = tmp;
else if(tmp.x>0)b[++top2] = tmp;
}
long long ans = 0;
sort(a+1,a+1+top1,cmp);
sort(b+1,b+1+top2,cmp2);
int kk = 0;
for(int i=1; i<=top1; i++)
{
// cout<<b[i].m<<"*"<<endl;
if(a[i].m<0)
{
if(i>top1-1)continue;
else
{
a[i+1].m += a[i].m;
}
}
else
{
int hh = (a[i].m+k-1)/k;
ans+=2*(hh)*abs(a[i].x);
a[i].m = a[i].m%k;
if(i<top1&&a[i].m)
a[i+1].m-=(k-a[i].m);
}
}
// cout<<ans<<endl;
for(int i=1; i<=top2; i++)
{
// cout<<b[i].m<<"*"<<endl;
if(b[i].m<0)
{
if(i>top2-1)break;
else
{
b[i+1].m += b[i].m;
}
}
else
{
int hh = (b[i].m+k-1)/k;
ans+=2*(hh)*abs(b[i].x);
b[i].m = b[i].m%k;
if(i<top2&&b[i].m)
b[i+1].m-=(k-b[i].m);
}
}
cout<<ans<<endl;
return 0;
}
TLE代码:
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
struct node
{
long long
x,m;
} a[2000],b[2000];
int cmp(node a,node b)
{
return a.x<b.x;
}
int cmp2(node a,node b)
{
return a.x>b.x;
}
int main()
{
int n,k;
cin>>n>>k;
node tmp;
int top1 =0 ;
int top2 =0 ;
for(int i=1; i<=n; i++)
{
scanf("%lld%lld",&tmp.x,&tmp.m);
if(tmp.x<0)a[++top1] = tmp;
else if(tmp.x>0)b[++top2] = tmp;
}
long long ans = 0;
sort(a+1,a+1+top1,cmp);
sort(b+1,b+1+top2,cmp2);
int kk = 0;
for(int i=1; i<=top1; i++)
{
if(a[i].m<=0)continue;
double gg = a[i].m*1.0/k;
long long u = ceil(gg);
kk = k;
if(a[i].m>=k)
{
kk-=a[i].m%k;
ans+=(2*u*abs(b[i].x));
}
else
{
ans+=(2*abs(a[i].x));
kk-=a[i].m;
}
if(a[i].m%k==0)continue;
while(kk>0)
{
int j = i+1;
if(kk<a[j].m)
{
a[j].m-=kk;
kk= 0;
break;
}
else
{
a[j].m = 0;
kk-=a[j].m;
}
j++;
if(j>top1)break;
//cout<<kk<<endl;
}
}
//cout<<ans<<endl;
for(int i=1; i<=top2; i++)
{
// cout<<b[i].m<<"*"<<endl;
if(b[i].m<=0)continue;
double gg = b[i].m*1.0/k;
long long u = ceil(gg);
kk = k;
if(b[i].m>=k)
{
kk-=b[i].m%k;
ans+=(2*u*abs(b[i].x));
}
else
{
kk-=b[i].m;
ans+=(2*abs(b[i].x));
}
if(b[i].m%k==0)continue;
while(kk>0)
{
int j = i+1;
if(kk<b[j].m)
{
b[j].m-=kk;
kk= 0;
break;
}
else
{
b[j].m = 0;
kk-=b[j].m;
}
j++;
if(j>top2)break;
// cout<<kk<<endl;
}
}
cout<<ans<<endl;
return 0;
}