不僅要熟練掌握基礎演算法,豐富的想象力亦是非常重要的。
二分查詢的複雜度是o(logn)的,即便n變得很大,對數時間的演算法依然非常快速。
如果把最開始的問題中的n的限制條件改為1<=n<=1000,最初的四重迴圈o(n的4次方)複雜度的演算法顯然不夠,必須改進演算法。
for(int a=0;a上為最初程式的迴圈部分。最內側關於d的迴圈所做的事情就是
檢查是否有d使得k[a]+k[b]+k[c]+k[d]=m
通過對式子進行移項,就能得到另一種表達方式
檢查是否有d使得k[d]=m-k[a]-k[b]-k[c]
即判斷是否有m-k[a]-k[b]-k[c]
根據上述推論,讓我們來考慮一下快速檢查的方法。
記所要查詢的值m-k[a]-k[b]-k[c]為x。
預先把陣列排好序,然後看k**的數字:
如果它比x小,x只可能在它的後半段。
如果它比x大,x只可能在它的前半段。
如果再將上述方法運用到已經減半的x的存在區間上,x的存在區間就變成了初始的1/4.
反覆操作,不斷縮小x的存在區間,最終確定x存在與否。
二分搜尋演算法每次將候選區間大致縮小為原來的一半。
因此,要判斷長度為n的有序陣列k中是否包含x,只要反覆執行約log₂n次即可。
二分查詢的複雜度是o(logn)的,我們稱稱這種階的執行時間為對數時間。
即便n變得很大,對數時間的演算法依然非常快速。n1
10100
1000
1e61e9
log₂n03
7102030
將最內側的迴圈替換成二分搜尋演算法之後
排序o(nlogn)
迴圈o(n³logn)
o(n³logn)比o(nlogn)大,所以這了合起來當作是o(n³logn)
於是我們得到了在o(n³logn)時間內解決的辦法
#include#include//sort函式標頭檔案。sort(begin,end,cmp),cmp引數可以沒有,如果沒有預設非降序排序。
using namespace std;
const int max_n = 1000;
int n=3,m=10,k[max_n]=;
//int n=3,m=9,k[max_n]=;
bool binary_search(int x);
//int n=3,m=9,k[max_n]=;
//儲存兩個數的和序列
int kk[max_n*max_n];
bool binary_search(int x){
//x的物件範圍是kk[l],kk[l+1],...,kk[r-1]
int l=0,r=n*n;
//反覆操作直到存在範圍為空
while(r-l>=1){
int i=(l+r)/2;
if(kk[i]==x) return true;//找到x
else if(k[i]本題既需要二分搜尋的基礎演算法知識,也需要將四個數分成兩兩考慮的想象力.
像這樣從複雜度較高的演算法出發,不斷降低複雜度直至滿足問題要求的過程,也是設計演算法時經常會經歷的乙個過程。
挑戰程式設計競賽學習筆記1
const定義的變數值在程式執行過程中不允許發生改變 printf根據格式符輸出對應型別 putchar只能輸出字元 puts可以輸出字串 設計高效且正確的演算法 正確地實現 並且,為了設計演算法,靈活的想象力 演算法的基礎知識 也是必不可少的。程式設計競賽就是以程式設計為主題舉辦的競賽。n個紙片,...
挑戰程式設計競賽學習筆記2
書中只給出演算法函式,程式所用資料預設已讀入程式並儲存在全域性變數中。以高效演算法為目標,需要正確估算各種演算法的複雜度。縮短執行時間,主要應該從複雜度入手。程式都從標準輸入按指定格式讀入資料 輸入資料已經由main函式讀入並儲存在全域性變數中 通過呼叫solve函式來求解 在設計滿足問題要求的演算...
挑戰程式設計競賽學習筆記4
想象力很重要,要從複雜中看出本質。暴搜雖然幾乎萬能,但是越複雜時間越長,能不用就不用。n只螞蟻,均以1cm s的速度,在長為lcm的桿子上爬行。爬到端點掉落,相遇時掉頭爬,已知每只螞蟻據竿子左端的距離xi,朝向未知。求所有螞蟻落下桿子所需的最短時間和最長時間。1 l 1e6 1 n 1e6 0 x ...