TIOJ 1404 照亮的山景

Description


在一片山的上空,高度為 t 處有 n 個處於不同水平位置的燈泡,如上圖所示。
如果山的邊界上某一點與第 i 盞燈的連線不經過任何山稜線上的一點,我們稱第 i 盞燈可以照亮該點。
請問至少要打開幾盞燈,才能照亮山上每一個轉折點?

Input Format

輸入可能包含多筆測試資料。

對於每筆測試資料:
1 列:一個整數 m (1m100,000),代表山稜折線的轉折點個數。
2m+1 列:xi,hi,依序代表轉折點的水平座標以及垂直海拔高度。(100,000xi,hi100,000)
所有轉折點座標將以 x 座標由小到大排列。
m+2 列:n,t,其中 n 代表燈泡個數,t 代表所有燈泡的高度,該高度必定高於整座山最高轉折點的高度。
(1n,t100,000)
m+3 列:有 n 個整數 b1,b2,,bn,代表 n 個燈泡的水平座標,且依座標值由小到大排列。

Output Format

如果可以點亮某幾盞燈而照亮所有轉折點,請輸出最少需要點亮的燈泡數量。
否則請輸出 "you need more bulbs!"(不包含雙引號)。

Sample Input

6
1 1
3 3
4 1
7 1
8 3
11 1
4 5
1 5 6 10

6
1 1
3 3
4 1
7 1
8 3
11 1
2 5
1 5

Sample Output

2
you need more bulbs!

Solution

首先,不難發現某個轉折點能被照到若且唯若有顆燈泡的位置在水平線 y=t 上的某個開區間內。如果我們能求出每個轉折點對應的開區間,問題就被轉成下面這個形式:給定 R 上的 m 個開區間 {(li,ri)}mi=1,從 b1,,bnR 中選出最少的點使得每個區間至少包含一個被選中的點。這個問題有個簡單的貪婪解法,可以在 O(mlogm+n) 時間內解決。

那麼要怎麼算出每個轉折點對應的開區間呢?假定我們想算 Pi:=(xi,hi) 的左界 li,只要找到 1ji1 使得 ¯PjPi 的斜率最小就行了。可以發現,這個 Pj 必定在「P1,,Pi1 形成的上凸包 (upper convex hull) 邊界」上;此外,「某個 j=j 最小化 ¯PjPi 的斜率」,若且唯若「¯PjPi 在『P1,,Pi 形成的上凸包邊界』上」,也就是 l1,,lm (以及 r1,,rm) 可由 Andrew's 演算法O(m) 時間內求得。
最佳解 Pj 在上凸包邊界 (紅色) 上,且 ¯PjPi (藍色) 成為新上凸包邊界的一部份。

我的 code:
https://ideone.com/z7J87D

以下雜談。其實這題原本和出處 CEOI 2000 Problem 6 一樣,要求照亮整座山 (包含稜線),而照亮所有的轉折點並不能保證這件事情 (why?);不幸的是,刘汝佳的《算法艺术与信息学竞赛》裡面的解法,也只考慮了所有的轉折點是否被照亮 (因此也是假解)。我在向 TIOJ 管理員反應了這件事後,他就修正題目敘述了www。

那麼考慮原始題目 m,n200,有沒有一個好的正解呢?我有想到一個 O(mnlog(mn)) 時間複雜度的做法,只是稍嫌麻煩,等某天我上傳題目至 ZJ 後再來介紹。

留言

  1. 為甚麼照亮所有轉折點不代表照亮整座山><

    回覆刪除
    回覆
    1. 沒想到這裡有人留言www

      考慮轉折點為 A(0, 0), B(1, 10), C(2, 0), D(6, 0), E(7, 10), F(8, 0) 的情況
      如果有兩顆燈泡高度在 13 且位置在 0, 8
      不難發現第一顆燈泡照亮ABD 第二顆燈泡照亮CEF
      但兩顆燈泡都照不到盆地中點 (4, 0)
      建議可以畫圖 會更清楚是怎麼回事

      刪除
    2. wow 感謝回覆><
      沒想到是再次來翻文章的時候才發現留言被回了 <(_ _)>

      刪除

張貼留言

這個網誌中的熱門文章

2020 全國賽驗題心得

水母上 Divide-and-Conquer

109 學年度全國資訊學科能力競賽各題詳解