NOIP2017普及組正式賽 跳房子

2021-08-11 02:18:08 字數 4709 閱讀 5398

這一題很有它的價值,我都要認真思考一番才能夠想到方法。
先講一下題目大意

題目描述

跳房子,也叫跳飛機,是一種世界性的兒童遊戲,也是中國民間傳統的體育遊戲之一。跳房子的遊戲規則如下:

在地面上確定乙個起點,然後在起點右側畫 n 個格仔,這些格仔都在同一條直線上。每個格仔內有乙個數字(整數),表示到達這個格仔能得到的分數。玩家第一次從起點開始向右跳,跳到起點右側的乙個格仔內。第二次再從當前位置繼續向右跳,依此類推。規則規定:玩家每次都必須跳到當前位置右側的乙個格仔內 。玩家可以在任意時刻結束遊戲,獲得的分數為曾經到達過的格仔中的數字之和。

現在小 r 研發了一款彈跳機械人來參加這個遊戲。但是這個機械人有乙個非常嚴重的缺陷,它每次向右彈跳的距離只能為固定的 d。小 r 希望改進他的機械人,如果他花 g 個金幣改進他的機械人,那麼他的機械人靈活性就能增加 g,但是需要注意的是,每次彈跳的距離至少為 1。具體而言,當g < d時,他的機械人每次可以選擇向右彈跳的距離為 d-g, d-g+1,d-g+2,…,d+g-2,d+g-1,d+g;否則(當g ≥ d時),他的機械人每次可以選擇向右彈跳的距離為 1,2,3,…,d+g-2,d+g-1,d+g。

現在小 r 希望獲得至少 k 分,請問他至少要花多少金幣來改造他的機械人。

輸入

第一行三個正整數 n,d,k,分別表示格仔的數目,改進前機械人彈跳的固定距離,以及希望至少獲得的分數。 相鄰兩個數之間用乙個空格隔開。

接下來 n 行,每行兩個正整數�� �� , �� �� ,分別表示起點到第i個格仔的距離以及第i個格仔的分數。 兩個數之間用乙個空格隔開。 保證�� �� 按遞增順序輸入。

輸出

共一行,乙個整數,表示至少要花多少金幣來改造他的機械人。若無論如何他都無法獲得至少 k 分,輸出-1。
樣例輸入

【輸入樣例 1】

7 4 10

2 6

5 -3

10 3

11 -3

13 1

17 6

20 2

【輸入輸出樣例 2】

7 4 20

2 6

5 -3

10 3

11 -3

13 1

17 6

20 2

樣例輸出

【輸出樣例 1】

2【輸入輸出樣例 1 說明】

花費 2 個金幣改進後,小 r 的機械人依次選擇的向右彈跳的距離分別為2,3,5,3,4,3,先後到達的位置分別為 2,5,10,13,17,20,對應 1, 2, 3, 5, 6, 7 這 6 個格仔。這些格仔中的數字之和 15 即為小 r 獲得的分數。

【輸入輸出樣例 2】

-1【輸入輸出樣例 2 說明】

由於樣例中 7 個格仔組合的最大可能數字之和只有 18 ,無論如何都無法獲得 20 分。

資料範圍限制

本題共 10 組測試資料,每組資料 10 分。對於全部的資料滿足1 ≤ n ≤ 500000,1 ≤ d ≤2000,1 ≤ xi,k≤ 10^9 , |s i | < 10^ 5 。

對於第1,2 組測試資料,n ≤ 10;

對於第3,4,5組測試資料, n ≤ 500

對於第 6,7,8 組測試資料,d = 1

這一題有一點難了,不過,這畢竟是noip普及組第四題嘛!

正解——二分+單調佇列。

首先二分答案,然後就可以用乙個單調佇列來做(記得要維持好單調佇列)

時間複雜度就不用說了,相信讀者們都知道(此題可過)。

l:=0;//head

r:=a[n,1]+d;//tail

ans:=-1;//輸出的最小價值

while l<=r do

begin

mid:=(l+r) div

2;//二分變數

if pd(max(1,d-mid),mid+d) then

//pd是用來判斷是否成立的,在下面的單調佇列有講

begin

ans:=mid;

r:=mid-1;

endelse l:=mid+1;

end;

writeln(ans);

單調佇列(判斷能否得到k價值)部分:

function pd(zx,zd:longint):boolean;

var f,q:array[0..500000] of int64;

i,j,head,tail,last:longint;

begin

head:=1;

tail:=1;

last:=-1;//用來優化時間的

q[1]:=0;

f[0]:=0;

for i:=1 to n do

begin

f[i]:=0;

for j:=last+1 to i-1

do begin

if (a[j,1]+zx<=a[i,1]) and (a[j,1]+zd>=a[i,1]) then//判斷能否從a[j,1]跳到a[i,1]

begin

while (f[q[tail]]and (head<=tail) do

dec(tail);//刪尾

inc(tail);

q[tail]:=j;

last:=j;

end;

end;

while ((a[q[head],1]+zd1]) or (a[q[head],1]+zx>a[i,1])) and (head<=tail) do

inc(head);//移頭

if (head>tail) then f[i]:=-maxlongint

else f[i]:=f[q[head]]+a[i,2];//找到從零點到a[i,1]的最大獲得價值

if f[i]>=k then exit(true);

end;

exit(false);

end;

還是上一下源**吧!

var

a:array[0..500000,1..2] of longint;

n,d,k,i,l,r,ans,mid:longint;

function

max(x,y:longint):longint;

begin

if x>y then

exit(x)

else

exit(y);

end;

function

pd(zx,zd:longint):boolean;

var f,q:array[0..500000] of int64;

i,j,head,tail,last:longint;

begin

head:=1;

tail:=1;

last:=-1;

q[1]:=0;

f[0]:=0;

for i:=1

to n do

begin

f[i]:=0;

for j:=last+1

to i-1

dobegin

if (a[j,1]+zx<=a[i,1]) and (a[j,1]+zd>=a[i,1]) then

begin

while (f[q[tail]]and (head<=tail) do

dec(tail);

inc(tail);

q[tail]:=j;

last:=j;

end;

end;

while ((a[q[head],1]+zd1]) or (a[q[head],1]+zx>a[i,1])) and (head<=tail) do

inc(head);

if (head>tail) then f[i]:=-maxlongint

else f[i]:=f[q[head]]+a[i,2];

if f[i]>=k then

exit(true);

end;

exit(false);

end;

begin

assign(input,'jump.in');reset(input);

assign(output,'jump.out');rewrite(output);

readln(n,d,k);

for i:=1

to n do

read(a[i,1],a[i,2]);

l:=0;

r:=a[n,1]+d;

ans:=-1;

while l<=r do

begin

mid:=(l+r) div

2; if pd(max(1,d-mid),mid+d) then

begin

ans:=mid;

r:=mid-1;

endelse l:=mid+1;

end;

writeln(ans);

close(input);

close(output);

end.

這些地方都很容易理解,就是如何實現,因為那些細節真的是太多了!

(今年noip普及組沒能ak,真的是不幸中的不幸)

NOIP 2017 普及組 初賽

noip 2017 普及組 初賽 頭一次,短時間內把同年的 提高組 初賽 普及組 初賽 題目做了一遍。感覺是,普及組的題目相比提高組,真是弱爆了,完全不在乙個層次,題目做下來真的很菜。一 單項選擇題 1.補碼計算原碼,保留首位的符號位不變,剩下的位取反加1.補碼 10101011 補碼取反 1101...

NOIP2017普及組 棋盤

noip2017 有乙個m m的棋盤,棋盤上每乙個格仔可能是紅色 黃色或沒有任何顏色的。你現在 要從棋盤的最左上角走到棋盤的最右下角。任何乙個時刻,你所站在的位置必須是有顏色的 不能是無色的 你只能向上 下 左 右四個方向前進。當你從乙個格仔走向另乙個格仔時,如果兩個格仔的顏色相同,那你 不需要花費...

NOIP2017普及組 棋盤

棋盤 有乙個m m的棋盤,棋盤上每乙個格仔可能是紅色 黃色或沒有任何顏色的。你現在 要從棋盤的最左上角走到棋盤的最右下角。任何乙個時刻,你所站在的位置必須是有顏色的 不能是無色的 你只能向上 下 左 右四個方向前進。當你從乙個格仔走向另乙個格仔時,如果兩個格仔的顏色相同,那你 不需要花費金幣 如果不...