網頁

顯示具有 Divide&Conquer 標籤的文章。 顯示所有文章
顯示具有 Divide&Conquer 標籤的文章。 顯示所有文章

2014年2月13日 星期四

UVa 10776 Determine The Combination

想法:

直接舉例子來講,假設字串aaabbc(編號012345),取3個(n==3),我們先假設ans這個容器來存放所選的字元。

首先進入第一層遞迴後,表示要選一個字元放到ans[0],能選的字元為0~5,for loop 0~5,先放0('a')到ans。然後進入第二層遞迴,能選的字元變成1~5,for loop 1~5,放入1('a')到ans。再進入第三層遞迴,能選的字為2~5,for loop 2~5,放入2('a')到ans。進入第四層遞迴後發現ans.size()==n,因此輸出答案。

接下來退出第四層回到第三層,跳出ans的字(ans.pop_back()),找下一個字元,因為避免重複,所以用while loop找到下一個不一樣的字,放入3('b')到ans,以此類推...

把第三層for loop跑完後,回到第二層,一樣跳出第二層的字,找下一個字不一樣的字元,然後繼續進入第三層。....剩下以此類推。


2014年1月5日 星期日

UVa 10245 The Closest Pair Problem

求任兩點的最短距離,如果全部枚舉的話,時間複雜度n^2,一定會TLE。

想法:
  • 將所有點依x座標排序
  • 從中間切開,將所有點分成左右兩個集合(設line為中線x座標)
  • 左右兩邊各求出任兩點最小值a,b,設d為min(a,b)
  • 那麼現在只要枚舉(line+-d)這範圍內的點有沒有比d還更小的值即可

遞迴定義:
  • divide(point_type a[], low, high)  
    • 求出a[low]~a[high]範圍內任兩點的最短距離
  • combine(point_type a[], low, mid, high, min_left, min_right)
    • d=min(min_left,min_right)
    • line=(a[mid].x+a[mid+1].x)/2
    • 合併左右兩個集合,並確認在(line+-d)的範圍內有沒有比d更小的值,最後回傳最小值

注意輸入輸出皆要用double