1. 程式人生 > >算法學習(十)

算法學習(十)

last 發現 != 交換 algo 例子 答案 數據集 earch

1.Binary Search(二分法)

說明:二分法搜索是編程一項常見的任務,因為它是用於搜索排序數組(這就是我們學習排序的原因)和解決數學方程的方法。

我們的目標是解出如下形式的方程:

A * x + B * sqrt(x ^ 3) - C * exp(-x / 50) - D = 0

這裏A B和C都是正的,所以這個函數是單調的。x的解肯定存在於0到100的範圍內(0 <= x <= 100)。

解應該精確到0.0000001=1e-7或更好。

輸入數據:第一行中包含測試用例數。

下面的行中包含每個測試用例的4個數字,即A B C D四個值用空格隔開。

答案:應該包含解——也就是x的值,它滿足了給定的方程式——幾個答案(對於幾個測試用例)應該與空格分開。

例如:

input data:
2
0.59912051 0.64030348 263.33721367 387.92069617
15.68387514 1.26222280 695.23706506 698.72384731

answer:
73.595368554162 41.899174957955

測試數據:

6
9.20675416 0.87395008 1667.33525026 495.83581830
1.87353375 1.61305979 1376.91480917 1153.47175535
4.66566950 0.67303113 366.84269196 434.68812075
15.67052619 0.48875617 714.77221172 -264.23993463
14.69705865 0.69917802 297.42862112 1568.06585760
18.22457610 0.50751334 784.28709171 1720.63987051

代碼如下:

 1 import math  # 需要用到math模塊
 2 test_case = int(input())  # 測試用例數
 3 for i in range(test_case):
 4     case = input().split()   # 分別得到每行的A,B,C,D
 5     A = float(case[0])
 6     B = float(case[1])
 7     C = float(case[2])
 8     D = float(case[3])
 9     def func(x):
10         return A * x + B * math.sqrt(x ** 3) - C * math.exp(-x / 50) - D   #
建立個要求方程式,代入A,B,C,D 的值 11 low = 0 12 height = 100.0 13 n = low + (height - low) / 2.0 # 求中值 14 m = 100 # 因為發現代碼出現了無限循環,分析後,所有的解經過100次的循環都可以解出來,所有設定100次循環 15 while func(n) != 0 and m > 0: # 當方程不等於0,開始循環,可能就是因為n是小數,所有方程只能接近0,不能等於0,造成了無限循環 16 if func(n) > 0: # 所以添加100的循環次數限制,避免無限循環 17 height = n - 1.0 18 low = low 19 elif func(n) < 0: 20 low = n + 1.0 21 height = height 22 n = low + (height - low) / 2.0 23 m -= 1 # 減少一次循環 24 print(n, end= ) 25 26 輸出:61.34503889699867 84.37226003243683 56.756393017339064 15.062697470552255 78.1010605734923 82.05365393491547

  最後請教下各位大神,還有哪種方法能避免出現無線循環啊。

2.Selection Sort(選擇排序法)

說明:假設我們有N個值的數組,想對它們排序,就像冒泡排序一樣:

[3, 1, 4, 1, 5, 9, 2, 6, 5, 3]

我們方法如下:

在整個數組中,找到最大元素的位置(在上面的例子中,5是最大值9的索引);

將這個元素與最後一個元素交換(因為在排序的數組中,它應該是最後一個)——也就是位置N-1;

現在考慮長度為N-1的子數組,沒有最後一個值(已經“在正確的位置”);

在這個子數組中找到最大元素的位置(也就是整個數組中的第二大元素)-現在它將是索引7(值6所在的位置);

將它與子數組中的最後一個元素交換(例如,位置n-2);

現在考慮長度n-2的子數組(沒有兩個最後的元素)-執行下面的選擇和交換,等等;

當“子數組”減少到1時,算法就結束了。

例子:

[3, 1, 4, 1, 5, 9, 2, 6, 5, 3]      - max is 9 at position 5, swap 5-th with 9-th
[3, 1, 4, 1, 5, 3, 2, 6, 5], 9      - max is 6 at position 7, swap 7-th with 8-th
[3, 1, 4, 1, 5, 3, 2, 5], 6, 9      - max is 5 at position 4, swap 4-th with 7-th - they are equal!
[3, 1, 4, 1, 5, 3, 2], 5, 6, 9      - max is 5 at position 4, swap 4-th with 6-th
[3, 1, 4, 1, 2, 3], 5, 5, 6, 9      - max is 4 at position 2, swap 2-th with 5-th
[3, 1, 3, 1, 2], 4, 5, 5, 6, 9
...
[1], 1, 2, 3, 3, 4, 5, 5, 6, 9      - subarray of length 1 is reached, stop an algorithm.

分析:

這個算法需要讓N通過數組,在每次傳遞時,它平均執行N/2操作,所以它有O(N^2)“時間復雜度”,和冒泡排序一樣。然而,與冒泡排序不同的是,它並沒有在每次傳遞中執行n/2交換,只需要進行一次交換。這使得它工作的更快,對於大型數據集來說,需要更多

這樣的狡猾的算法。

您可以選擇最小值,而不是最大值,然後將它們與數組的開始交換。同樣,根據我們選擇最左或右的最大值(或最小值),排序可能是穩定的,也可能是不穩定的,這意味著它要麽保留或不保留相等元素的順序當我們排序對象,而不是數字時,這可能很重要。

問題陳述:

您要實現上面描述的算法,並在每次傳遞時打印出所選擇的最大值的索引。

輸入數據:第一行中包含數組的大小。

下一行包含數組本身(所有元素都是不同的)。

答案:應該包含每個傳遞的最大值的索引(N-1值)。

例如:

input data:
6
31 41 59 26 53 58

answer:
2 2 2 1 0

測試數據:

128
54 28 159 13 163 41 137 160 4 191 129 173 61 44 102 135 161 32 130 16 53 142 38 5 26 172 196 190 199 51 149 15 150 175 45 153 166 127 27 17 30 162 178 92 193 113 34 117 39 57 11 104 24 118 183 93 60 2 87 19 84 49 145 140 59 174 22 78 29 131 73 35 36 66 58 154 50 31 48 157 107 79 12 98 95 42 182 85 99 156 106 74 169 184 103 116 151 105 152 146 180 21 126 119 33 96 197 133 72 25 114 110 189 6 55 170 63 67 186 192 65 64 90 177 136 158 125 109

代碼如下:

test_case = int(input())  # 測試用例
data = input().split()  # 分隔字符
array = []
for i in data:
    array.append(int(i))   # 把字符轉化為整數

for i in range(test_case - 1):
    max_index = array.index(max(array))
    print(max_index, end= )   # 打印索引
    last_elem = array[-1]
    array[-1] = max(array)  # 交換最大值和最後一個值
    array[max_index] = last_elem
    array = array[:-1]  # 返回新數組

輸出:28 106 26 44 119 9 27 112 118 93 54 86 100 42 93 33 65 11 25 100 92 36 4 41 16 7 2 26 79 89 75 35 89 35 32 30 79 62 21 63 6 44 15 30 69 18 10 37 7 36 16 53 47 21 11 45 65 28 37 62 47 51 35 14 63 37 4 30 55 43 9 43 6 30 10 47 7 28 26 30 11 33 27 44 12 12 14 21 26 12 0 20 29 10 4 20 10 13 15 5 13 22 13 15 4 14 17 16 17 0 1 12 15 13 11 7 2 6 2 1 6 3 0 0 3 0 1 

算法學習(十)