作者:Chilldon螴暁鼕 | 来源:互联网 | 2023-08-26 17:35
题目地址:http:acm.zju.edu.cnonlinejudgeshowProblem.do?problemCode4096题意多组输入。有n封信要送到指定
题目地址: http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4096
题意 多组输入。
有n封信要送到指定地点,每次最多拿k封,重新拿信要回到位置0,求把所有信送完走的最小的距离
解题思路 贪心。
分x<0和x>0两部分 &#xff0c;计算只去不回的距离&#xff08;来回的距离*2即可&#xff09;。
在坐标轴上从远往近 &#xff08;相对于位置0来说&#xff09;贪心&#xff0c;每次都尽可能多的送信&#xff0c;用p记录每一段送信的最远距离&#xff0c;ans&#43;&#61;p。
最后取min&#xff08;ans*2-左侧最远点&#xff0c;ans*2-右侧最远点&#xff09;&#xff0c;最后一次走的最远&#xff0c;且只去不回。
一定要从远往近贪心&#xff01;&#xff01;这样走的距离才最小&#xff01;对最后一段送信的区间要特殊考虑下 。
一种可能的情况
好吧&#xff0c;我讲不清楚了(´&#xff65;Д&#xff65;)」具体看代码吧
ac代码 #include #include #include #include #include #include #include #include #include #include #include #define maxn 100005 typedef long long ll; using namespace std; struct node{ll pos,num;//位置pos,要送num封信friend bool operator <(node a,node b){return a.pos>b.pos;} }l[maxn],r[maxn]; ll t,n,k,x; ll half(node a[],ll numi) {ll res&#61;0,sum&#61;0,p&#61;0;//记录每一段的起始位置if(numi>&#61;1) p&#61;a[0].pos;for(ll i&#61;0;ik){res&#43;&#61;p;a[i].num-&#61;(k-(sum-a[i].num));p&#61;a[i].pos;break;}else //sum} int main() {//freopen("/Users/zhangkanqi/Desktop/11.txt","r",stdin);scanf("%lld",&t);while(t--){memset(l,0,sizeof(l));memset(r,0,sizeof(r));ll ans &#61; 0, numl &#61; 0, numr &#61; 0;scanf("%lld %lld", &n, &k);for (ll i &#61; 0; i 0){r[numr].pos &#61; x;r[numr&#43;&#43;].num&#43;&#43;;}else if (x <0){l[numl].pos &#61; -x;l[numl&#43;&#43;].num&#43;&#43;;}}sort(l, l &#43; numl);sort(r, r &#43; numr);ans&#43;&#61;half(l,numl);ans&#43;&#61;half(r,numr);printf("%lld\n",min(ans*2-l[0].pos,ans*2-r[0].pos));}return 0; }