列表

详情


NC14847. Masha与老鼠

描述

有一天Masha回到家,发现有n只老鼠在它公寓的走廊上,她大声呼叫,所以老鼠们都跑进了走廊的洞中。 
这个走廊可以用一个数轴来表示,上面有n只老鼠和m个老鼠洞。第i只老鼠有一个坐标𝑥𝑖,第𝑗个洞有一个坐标𝑝𝑗和容量𝑐𝑗。容量表示最多能容纳的老鼠数量。 
找到让老鼠们全部都进洞的方式,使得所有老鼠运动距离总和最小。老鼠i进入洞j的运动距离为|𝑥𝑖 − 𝑝𝑗
无解输出-1。

输入描述

第一行包含两个整数n,m,表示老鼠和洞的数量。
第二行包含n个整数𝑥1...𝑛,表示老鼠坐标。
接下来m行每行两个整数𝑝, 𝑐,表示每个洞的坐标和容量。

输出描述

输出最小运动距离总和或-1。

示例1

输入:

4 5 
6 2 8 9 
3 6 
2 1 
3 6 
4 7
4 7

输出:

11

示例2

输入:

7 2 
10 20 30 40 50 45 35 
-1000000000 10 
1000000000 1

输出:

7000000130

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++ 解法, 执行用时: 834ms, 内存消耗: 64676K, 提交时间: 2021-05-29 22:55:28

#include<bits/stdc++.h>
#define ll long long
#define x first
#define y second
using namespace std;
struct data{
	ll x,y;
	data():x(0),y(0){}
	data(ll _x,ll _y):x(_x),y(_y){}
	bool operator < (const data m) const{
		return x>m.x;
	}
};
const int N = 2e6 + 10;
int n,m;
priority_queue<ll,vector<ll>,greater<ll> > H0;
priority_queue<data> H1;
pair<ll,ll> p[N];
ll ans = 0 ,sum ;
int main(){
	//freopen("data.in","r",stdin);
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
		int x;
		scanf("%d",&x);
		p[i]=make_pair(x,-1);
	}
	sum=n;
	while(m--){
		int x,y;
		scanf("%d%d",&x,&y);
		p[++n]=make_pair(x,y);
		sum-=y;
	}
	if(sum>0) return puts("-1"),0;
	sort(p+1,p+1+n);
	for(int i=1;i<=n;++i){
		if(p[i].y==-1){
			ll w = 1e15;
			if(!H1.empty()){
				ll x = H1.top().x , y = H1.top().y;H1.pop();
				w = p[i].x+x;
				y--;
				if(y) 
					H1.push(data(x,y));
			}
			ans += w;
			H0.push(-p[i].x-w);
		}
		else{
			while(p[i].y&&!H0.empty()&&p[i].x+H0.top()<0){
				ll w = p[i].x + H0.top() ; H0.pop(); 
				ans += w ; 
				p[i].y-- ;
				H1.push(data(-p[i].x-w,1));	
			}
			if(p[i].y){
				H1.push(data(-p[i].x,p[i].y));
			}
		}
	}
	printf("%lld",ans);
	return 0;
}

上一题