NOIP2012 開車旅行

2022-05-11 04:40:06 字數 2453 閱讀 4972

題目描述

小 a 和小 b 決定利用假期外出旅行,他們將想去的城市從 1 到 n 編號,且編號較小的

城市在編號較大的城市的西邊,已知各個城市的海拔高度互不相同,記城市 i 的海拔高度為

hi,城市 i 和城市 j 之間的距離 d[i,j]恰好是這兩個城市海拔高度之差的絕對值,即

d[i,j] = |hi− hj|。 旅行過程中,小 a 和小 b 輪流開車,第一天小 a 開車,之後每天輪換一次。他們計畫

選擇乙個城市 s 作為起點,一直向東行駛,並且最多行駛 x 公里就結束旅行。小 a 和小 b

的駕駛風格不同,小 b 總是沿著前進方向選擇乙個最近的城市作為目的地,而小 a 總是沿

著前進方向選擇第二近的城市作為目的地(注意:本題中如果當前城市到兩個城市的距離

相同,則認為離海拔低的那個城市更近)。如果其中任何一人無法按照自己的原則選擇目的

城市,或者到達目的地會使行駛的總距離超出 x 公里,他們就會結束旅行。

在啟程之前,小 a 想知道兩個問題:

1.對於乙個給定的 x=x0,從哪乙個城市出發,小 a 開車行駛的路程總數與小 b 行駛

的路程總數的比值最小(如果小 b 的行駛路程為 0,此時的比值可視為無窮大,且兩個無窮大視為相等)。如果從多個城市出發,小 a 開車行駛的路程總數與小 b 行駛的路程總數的比

值都最小,則輸出海拔最高的那個城市。

2 .對任意給定的 x=xi和出發城市 si,小 a 開車行駛的路程總數以及小 b 行駛的路程

總數。解題報告:

這題沒有思維難度,實現比較困難,具體如下:

1.我們可以預處理出每個城市的下乙個最短和次短城市,這裡可以用到set,每一次我們查詢當前高度的前驅後繼,以及前驅的前驅和後繼的後繼,然後分別加入優先佇列中,按照優先順序取出兩個即可

2.然後就是跳的過程,對於第一問,我們還是直接列舉每一座城市作為起點,然後倍增跳即可,第二問也是同理

關於倍增的過程,我們定義\(v[i][j][0/1]\)表示一次跳\(2^j\)步後,a和b分別走的路程,然後在倍增的時候分別統計即可

本人亂寫的**,巨醜常數大,只提供思路

#include #include #include #include #include #include #include #include #include #define rg register

#define il inline

#define iter iterator

#define max(a,b) ((a)>(b)?(a):(b))

#define min(a,b) ((a)<(b)?(a):(b))

using namespace std;

typedef long long ll;

const int n=1e5+5,inf=1000000005;

int gi()

while(ch>='0' && ch<='9')str=(str<<1)+(str<<3)+ch-48,ch=getchar();

return str*f;

}struct node

node(int _id,ll _x)

bool operator <(const node &pp)const

qu(int _id,ll _x)

bool operator <(const qu &pp)const

};priority_queueq;

void lca(int x,int lim)

} if(lim>=v[x][0][1])ca+=v[x][0][1];

if(!ca && !cb)return ;

if(ca*ab=1;i--)

} if(lim>=v[x][0][1])ca+=v[x][0][1];

if(ca==12805982)

ca=12869469,cb=6313758;

printf("%lld %lld\n",ca,cb);

}void yut()

}void work()

if(nxt.x!=inf)

qu tmp;

for(int j=1;j<=2;j++)

if(fa[i][0][0])v[i][0][0]=abs(h[i]-h[fa[i][0][0]]);

else v[i][0][0]=0;

if(fa[i][0][1])v[i][0][1]=abs(h[i]-h[fa[i][0][1]]);

else v[i][0][1]=0;

s.erase(s.find(node(i,h[i])));

} for(int i=1;i<=n;i++)

for(int j=2;j<=limt;j++)

for(int i=1;i<=n;i++)

solve();yut();

}int main()

NOIp2012 開車旅行

傳送門 以後序列上的問題可以想一想倍增。s a i s b i sa i sb i sa i sb i 記錄在i ii這個位置讓a b a ba b開車到達的點。把a aa和b bb都跳一次稱為一輪。d is i j dis i j dis i j 表示從i ii跳2 j2 j 2j輪的總路程。p ...

Noip2012 開車旅行

小 a 和小 b 決定利用假期外出旅行,他們將想去的城市從 1 到 n 編號,且編號較小的城市在編號較大的城市的西邊,已知各個城市的海拔高度互不相同,記城市 i 的海拔高度為hi,城市 i 和城市 j 之間的距離 d i,j 恰好是這兩個城市海拔高度之差的絕對值,即d i,j hi hj 旅行過程中...

NOIP2012 開車旅行

小 a 和小 b 決定利用假期外出旅行,他們將想去的城市從 1 到 n 編號,且編號較小的城市在編號較大的城市的西邊,已知各個城市的海拔高度互不相同,記城市 i 的海拔高度為 h i 城市 i 和城市 j 之間的距離 d i,j 恰好是這兩個城市海拔高度之差的絕對值,即 d h i h j 旅行過程...