AtCoder #Contest 023-D. Go Home

題意

數軸上的整數節點住着一些人,下班後,他們要從公司(與homes不重疊,座標爲s)回家

每個人都很\(\mathbb{SELFISH}\),他們總是希望自己早點回家,只有一輛車,開的方向投票決定,問最小短路徑

題解

坑點:selfish不是一定投自己方向,比如

座標 1 2 3 4

人數 3 s 2 2

4節點的人如果先投自己方向,車:2 -> 3 -> 1 -> 4,路徑會變長

so,最邊上的人,人數更小的一邊反而會投靠另一邊,故而可以這樣處理(例):最右邊的人數加上最左邊的人數,ans += 兩者間路徑

調試記錄

處理特殊情況:所有節點在s同側,在左側與左邊求差,在右側與右邊求差

#include <cstdio>
#include <algorithm>
#include <cmath>
#define maxn 500005

using namespace std;

struct node{
	long long pos, num;
}a[maxn];

long long n, s, ans = 0;

bool cmp(node x, node y){ return (x.pos < y.pos); }

int main(){
	scanf("%lld%lld", &n, &s);
	
	for (long long i = 1; i <= n; i++) scanf("%lld%lld", &a[i].pos, &a[i].num);
	sort(a + 1, a + n + 1, cmp);
	
	long long left = 1, right = n;
	
	while (left <= right){
		if (a[right].pos <= s){
			ans += (s - a[left].pos);
			break;
		}
		if (a[left].pos >= s){
			ans += (a[right].pos - s);
			break;
		}
		
		ans += (a[right].pos - a[left].pos);
		if (a[left].num >= a[right].num){
			while (left < right && a[left].num >= a[right].num) a[left].num += a[right--].num;
		}
		else{
			while (left < right && a[right].num > a[left].num) a[right].num += a[left++].num;
		}
	}
	
	printf("%lld\n", ans);
	
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章