1. 程式人生 > 其它 >AtCoder Beginner Contest 230 D - Destroyer Takahashi

AtCoder Beginner Contest 230 D - Destroyer Takahashi

題意

給定N堵牆,一拳超人每次選一個範圍攻擊,如果某個牆有任意一格在這個範圍內,這堵牆就銷燬了。

求:最小的揮拳數量


題解

條件1:要打掉所有牆。

條件2:揮拳數量要儘量小。

條件3:一次揮拳只能銷燬一定範圍內的牆。

性質1:在揮拳數量儘量小的情況下,所有牆必須被銷燬。

性質2:如果兩次揮拳能夠合併成一次揮拳且滿足性質1,就應當計數為1。

性質3:揮拳一定是有邏輯、有順序的。

答案1:應當對所有牆以左端點為主鍵,右端點為次鍵排序。(條件3/性質3/性質1)

反證1:不能直接對每個牆的右端點進行攻擊,因為一個大牆可以覆蓋整個區間。

答案2:定義minR為一定範圍內能夠攻擊的牆的右端點的最小值,那麼[minR,minR+D-1]就是能夠摧毀的牆的左端點的合法取值區間。(性質1/性質2)

複雜度:{O(n),O(n)}



#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int MAXN = 4e5; struct Wall { int l, r; bool operator <(const Wall &another)const { if (l == another.l)return r < another.r; return l < another.l; } }s[MAXN]; int main() { int n, D; scanf("%d%d", &n, &D); for (int i = 1; i <= n; i++) { scanf("%d%d", &s[i].l, &s[i].r); } sort(s + 1, s + n + 1); int cnt = 0; for (int i = 1; i <= n;i++) { int minR=s[i].r; cnt++; for (int j = i + 1;s[j].l<=minR+D-1&&j<=n; j++) { minR = min(minR, s[j].r); i = j; } } printf("%d\n", cnt); return 0; }
TRANSLATE with x English
Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian
Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian
TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back