[USACO15OPEN] Trapped in the Haybales S题解

题目描述

FJ 收到了 N 捆干草,并将它们放置在连接房屋与谷仓的道路上。第 j 捆干草的大小为 Sj​,位置为 Pj​。Bessie 一开始在 B 处,不与任何一捆干草的位置重合。

Bessie 可以在干草捆之间任意移动(也可以到达干草捆所在的位置),但不能越过干草捆。但凡事总有例外:当 Bessie 进行了长度为 D 的冲刺后,她就可以击碎一捆大小严格小于 D 的干草,这意味着这捆干草不复存在。

由于某些原因,FJ 希望把 Bessie 困在最左边与最右边的干草捆之间。为此,他希望将某一捆干草的大小增加一些。如果可能把 Bessie 困住,请输出他最少需要增加多少干草;否则输出 -1

1⩽N⩽105,1⩽Si​,Pi​,B⩽109。

输入格式

第一行,两个整数 N,B,分别表示干草捆数量与 Bessie 所在位置。

接下来 N 行,第 i 行为两个整数 Si​,Pi​,分别表示第 i 捆干草的大小与位置。

输出格式

如果可能把 Bessie 困住,输出一行一个整数,表示最少需要增加多少干草;否则输出 -1

Translated by KHIN.

显示翻译

题意翻译

输入输出样例

输入 #1复制

5 7
8 1
1 4
3 8
12 15
20 20

输出 #1复制

4

思路

贪心+DP。

代码见下

#include<bits/stdc++.h> 
using namespace std;
long long n,b,db=0,l,r,lk=1e18+7;
struct one{
    long long s,p;  
}a[100005];
bool cmp(one a1,one b1){
    return a1.p<b1.p;
}
int main(){
	cin>>n>>b;
    for(int i=1;i<=n;i++){
        cin>>a[i].s>>a[i].p;
    }
    sort(a+1,a+n+1,cmp);
   if(a[1].p>=b||a[n].p<=b){
       cout<<-1<<endl;
    }
    else{
         for(int i=2;i<=n;i++){
             if(a[i].p>=b){
                 db=i-1;
                 break;
             }
         }
        r=db+1;
    	for(int i=db;i>=1;i--) {
    		while(r<=n&&a[r].p-a[i].p>a[r].s){
                r++;
            }
    		if(r>=n+1){
                break;
            }
    		lk=min(lk,a[r].p-a[i].p-a[i].s);
    	}
    	l=db;
    	for(int i=db+1;i<=n;i++){
    		while(l>=1&&a[i].p-a[l].p>a[l].s){
                l--;
            }
    		if(l<=0){
                break;
            }
    		lk=min(lk,a[i].p-a[l].p-a[i].s);
    	}
        if(lk>=1e15){
            cout<<-1<<endl;
        }
        else{
            cout<<max(lk,0ll)<<endl;
        }
    }
	return 0;
}

posted @ 2025-10-15 21:52  bz02_2023f2  阅读(9)  评论(0)    收藏  举报  来源