Problem J 屠龍勇者(尺取法)

2021-10-11 22:48:29 字數 3169 閱讀 2158

problem j. 屠龍勇者

又是乙個俗套的故事,吉奧馬丘國的公主被惡龍抓走了。作為吉奧馬丘國最出名的勇者,ervinxie

理所當然的擔負起了拯救公主,成為屠龍勇士的責任。ervinxie 極其強大,他攻無不克、戰無不勝,對

付惡龍簡直就是以大欺小,恃強凌弱、虎入羊群、泰山壓卵、席捲八方、翻手為雲、覆手為雨。所以他擊

敗惡龍完全不需要什麼準備。但是,傳說屠龍勇士終將成為惡龍。ervinxie 為了自己下半生的幸福,當

然不能容忍自己成為一條惡龍。所以,ervinxie 從吉奧馬丘國的煉金大師 xirhxq 那裡學習了驅魔法

陣的製作方法,同時煉金大師 xirhxq 好心的給 ervinxie 提供了兩套一次性傳送陣法。ervinxie 為了

湊齊驅魔法陣的布陣材料,需要前往豎炬劫溝旁的季蒜脊河裡採集材料。季蒜脊河是一條神奇的河,它

裡面藏著很多奧秘。季蒜脊河裡每一公尺都有且僅有著乙個特殊的煉金材料。為了能夠成功布置驅魔法陣,

同時盡快救出公主。ervinxie 打算使用一次性傳送陣法傳送到季蒜脊河中某乙個位置(ervinxie 可以指

定是哪乙個位置),然後在河中收集煉金材料。收集完材料後,立馬傳送去惡龍谷拯救公主。

已知這個世界中一共有 k 種煉金材料,分別使用 1, 2, 3…k 編號。

煉金法陣的布置方法是將相應煉金材料按直線擺放就能成功布置。法陣一共需要 s 個煉金材料, 法陣

的布置方法通過 a1, a2, a3 · · · as 給出,其中 ai 代表的是煉金材料種類。可能存在不同位置需要擺放相同

種類煉金材料的情況。那麼這種材料就需要收集多個。

季蒜脊河的長度為 len, 從源頭開始直到末尾,每公尺存在的煉金材料為 b1, b2, b3 · · · blen。bi 是煉金材

料的種類。

問 ervinxie 至少需要經過多少個煉金材料(包含收集的)才能去屠龍拯救公主。當然,如果 ervinxie

注定收集不全材料,他仍然會去拯救公主,和公主在一起… 即使是以惡龍的身份。

例如:季蒜脊河 5 公尺長,材料為 [1, 2, 1, 3, 2], 法陣的布置方法為 [1, 2, 3, 2],那麼 ervinxie 可以直接

傳送到河裡的第 2 個位置,往後收集材料,最終按照順序收集了 [2, 1, 3, 2] 材料後,能夠完成法陣,此時

傳送去惡龍谷拯救公主。經過了 4 個煉金材料.

ps:不會吧不會吧,你不會認為 ervinxie 會按收集順序擺放法陣吧?ervinxie 只是懶,不是蠢。他

當然知道材料收集夠了,擺放可以自己按順序擺。

input

第一行乙個數字 k,代表這個世界中存在的煉金材料種類數。1 ≤ k ≤ 5000

第二行乙個數字 s,代表法陣的長度。1 ≤ s ≤ 106

第三行 s 個數字,代表法陣的布置方式 ai 。1 ≤ ai ≤ k

第四行乙個數字 len,代表季蒜脊河的長度。1 ≤ len ≤ 2 × 106

第五行 len 個數字 bi

, 代表季蒜脊河每公尺存在的煉金材料的種類。1 ≤ bi ≤ k

output

輸出為一行

如果能夠收集完材料,輸出乙個數字,表示 ervinxie 至少需要經過多少個煉金材料(包含收集的)

才能去屠龍拯救公主。

否則… 輸出 「dragonxie」 (不含引號)

examples

standard input standard output54

1 2 3 2

51 2 1 3 2

45000

1512

51 2 3 4 5

dragonxie

note

輸入資料較大,推薦使用 scanf 或者自行實現快速讀

//模擬

#include

using

namespace std;

#define inf 0x3f3f3f3f

const

int n =

2e6+10;

const

int m =

5005

;queue<

int> q;

//利用棧來找最優解,每當佇列中前面的元素不必要時,更新佇列的長度,佇列的長度即為解的值

vector<

int> b[m]

;//存第i種元素的位置

int s[m]

, vis[m]

;//s存第i元素需要的數目,vis陣列存第i元素的數目是否已經滿足條件

int add[m]

, dis[n]

;// add陣列存第i種元素現在還在佇列中的第乙個元素,dis標記第i個位置能不能捨去的

intmain()

cin >> m;

int flag =0;

for(i =

0; i < m; i++)}

else

if(b[a]

.size()

== s[a])if

(flag >= len)}if

(flag >= len)

cout << ans <<

'\n'

;else

puts

("dragonxie");

return0;

}

//尺取法模板

#include

using

namespace std;

const

int m =

2e6+10;

const

int n =

5005

;int num1[n]

, num2[n]

, a[m]

;int

main()

cin >> len;

for(

int i =

1; i <= len; i++

) cin >> a[i]

;while

(r <= len)

while

(now >= n)}if

(ans ==

1e9)

puts

("dragonxie");

else

cout << ans <<

'\n'

;return0;

}

演算法 尺取法

我們先來介紹一下尺取法。尺取法,顧名思義,像尺子一樣,一塊一塊的擷取。題目翻譯 給定長度為n的數列整數a0,a1,a2,a3 an 1以及整數s。求出綜合不小於s的連續子串行的長度的最小值。如果解不存在,則輸出0。限制條件 100s 10 8 這裡我們拿第一組測試資料舉例子,即 n 10,s 15,...

尺取法練習

mr wolfram 的csdn 部落格 hopeforbetter的csdn部落格,尺取法顧名思義就像尺子一樣,當測量乙個物體時,你不一定從開始的位置測量,你可以從任意乙個位置st開始,當然前提是尺子夠長,然後你再讀出尾部en的數,尾部減去開始的位置en st,就是這個物體的長度。尺取法就是這個思...

尺取法基礎

p1638 逛畫展 題意 求最短區間包含所有畫家。思路 利用兩個變數來維護區間,如果區間不滿足條件r 滿足的話,l 直到區間最小。includeusing namespace std int a 1000005 b 1000005 int main b a l if b a l 0 k l else...