AtCoder Grand Contest 023 D - Go Home

在這裏插入圖片描述

題意

現在有一個數軸,有n個公寓。然後第i個公寓在xi位置上,且當前第i個公寓住pi個人。那麼現在我們從s開始出發。然後就會民主投票(多數人暴政),會選擇當前車子往左往右走一格,若票數相同就走左。當然每個人都是自私的且非常聰明的(這並不意味這他會一定往自己家走)。問最早什麼時候送完所有人。

前言

其實這題是我無聊找atcoder題時找到的。
當時想了想感覺沒思路,後來才發現奇妙無比。

題解

首先我們分析一下這些自私的人會怎麼選。

假設當前只剩下最左邊和最右邊的兩家公寓。
如果最左邊的公寓人數大於最右邊的人數,那麼最右邊的人數最聰明的做法是把全票投給最左邊的人。
爲什麼呢?
假設有這麼個數據:
4 10
1 10
12 5
13 5
14 5
你可能會想說最右邊的三個公寓齊心協力來對抗左邊的一個公寓。
然鵝當車子往右邊走的時候,人數會逐漸減少,反而讓最左邊的公寓佔了上風。
然後就往右邊走了一段不必要的路程。
感覺這個謙讓的思維很像“海盜分金問題”。

然後我們就一直把右邊的人投票投進去左邊的人,直到出現一個右邊的人大於左邊的人。
然後這樣週而復始。
當起點左邊或右邊沒有人反抗了之後,就可以停止了。

好一道思維神題。

代碼

#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
const int maxn=1000010;

int n;
long long st,ans,x[maxn],y[maxn];

int main()
{
	scanf("%d%lld",&n,&st);
	for (int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&x[i],&y[i]);
	}
	int l=1;
	int r=n;
	while (l<=r)
	{
		if (x[l]>=st) 
		{
			ans=ans+x[r]-st;
			break;
		}
		if (x[r]<=st)
		{
			ans=ans+st-x[l];
			break;
		}
		ans=ans+x[r]-x[l];
		if (y[l]>=y[r])
		{
			while (y[l]>=y[r] && l<r)
			{
				y[l]=y[l]+y[r];
				r--;
			}
		}
		else
		{
			while (y[l]<y[r] && l<r)
			{
				y[r]=y[r]+y[l];
				l++;
			}
		}
	}
	printf("%lld\n",ans);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章