c++可以說是c的加強版,其實,最大的差異在於c++提供物件導向的語法,雖然物件導向是很重要的概念,但是,APCS的範圍並不包含物件導向的語法與概念。
使用c++還有一些好處,其中一個好處是有一些內建的演算法,如果是使用C的話,內建的演算法就少很多了,而且語法也比較難懂一點。
快速排序
sort (c++內建函數)
sort(w, w+n);
完整的範例
#include <stdio.h>
**#include <algorithm>**
using namespace std;
int main(){
int n;
int w[1000];
int f[1000];
freopen("c471.txt", "r", stdin);
scanf("%d", &n);
for (int i = 0; i < n; i++){
scanf("%d", &w[i]);
}
**sort(w, w+n);**
printf("%d", w[0]);
return 0;
}
如果是個結構陣列,因為沒辦法判定要以哪個變數排序,就必須利用比較函數,定義比較的變數(或公式)
**bool cmp (box a, box b){
return a.f * b.w > b.f * a.w;
}**
sort (boxes, boxes+n, **cmp**);
完整的範例:
#include <stdio.h>
**#include <algorithm>**
using namespace std;
struct box {
int w;
int f;
};
**bool cmp (box a, box b){
return a.f * b.w > b.f * a.w;
}**
int main(){
int n;
freopen("c471.txt", "r", stdin);
scanf("%d", &n);
struct box boxes[n];
for (int i = 0; i < n; i++){
scanf("%d", &boxes[i].w);
}
for (int i = 0; i < n; i++){
scanf("%d", &boxes[i].f);
}
**sort (boxes, boxes+n, cmp);**
return 0;
}
給定一整數陣列a[0]、a[1]、…、a[99]且a[k]=3k+1,以value=100 呼叫以下兩函式,假設函式f1 及f2之while 迴圈主體分別執行n1 與n2 次 (i.e, 計算if 敘述執行次數,不包含 else if 敘述),請問n1 與n2 之值為何? 註: (low + high)/2 只取整數部分。
int f1(int a[], int value) { int r_value = -1; int i = 0; while (i < 100) { if (a[i] == value) { r_value = i; break; } i = i + 1; } return r_value; }
int f2(int a[], int value) { int r_value = -1; int low = 0, high = 99; int mid; while (low <= high) { mid = (low + high)/2; if (a[mid] == value) { r_value = mid; break; } else if (a[mid] < value) { low = mid + 1; } else { high = mid - 1; } } return r_value; }
(A) n1=33, n2=4 (B) n1=33, n2=5 (C) n1=34, n2=4 (D) n1=34, n2=5
APCS 2016年3月 第3題
a[0] = 1 a[1] = 4 … a[33]=100
low = 0, high = 99, mid =49 low = 0, high = 49, mid =24 low = 24, high = 49, mid = 36 …
下面哪組資料若依序存入陣列中,將無法直接使用二分搜尋法搜尋資料 (A) a, e, i, o, u (B) 3, 1, 4, 5, 9 (C) 10000, 0, -10000 (D) 1, 10, 10, 10, 100
APCS 2016年10月 第8題
提示: 二元搜尋法的前提是?
int A[8]={0, 2, 4, 6, 8, 10, 12, 14}; int Search(int x) { int high = 7; int low = 0; while (high > low) { int mid = (high + low)/2; if (A[mid] <= x) { low = mid + 1; } else { high = mid; } } return A[high]; }
給定一個 1x8的陣列A,A = {0, 2, 4, 6, 8, 10, 12, 14} 。上述函式Search(x) 真正目的是找到 A 之中大於 x的最小值。然而,這個函式有誤。 請問下列哪個函式呼叫可測出函式有誤? (A) Search (-1) (B) Search (0) (C) Search (10) (D) Search (16)
APCS 2017年3月 第1題
第一次A[mid]是6
每個選項的預期答案是 (A) Search (-1) → 0 (B) Search (0) → 2 (C) Search (10) →12 (D) Search (16) → 應該沒有答案
每個選項的實際答案是 (A) Search (-1) low = 0, high = 7, mid = 3 low = 0, high = 3, mid = 1 low = 0, high = 1, mid = 0; low = 0, high = 0 回傳 A[high] (B) Search (0) (C) Search (10) (D) Search (16)
APCS 2017年3月第4題
sort(point, point+n);
先求K為1及K為2 (範例2、範例1)
cout << (point[n-1]-point[0]) / k;
但範例1的答案只是正好一樣,那要怎麼算呢?
#include <iostream>
#include <algorithm>
using namespace std;
int point[50000];
int max_distance = 0;
int n, k;
int cover(int dis){
int coverage = point[0]+dis;//第一個基地台可以覆蓋的範圍
int cnt_station = 1;
for (int i = 0; i < n; i++){
if (point[i] > coverage){ //超出範圍
cnt_station ++;
coverage = point[i]+dis;
}
}
return cnt_station;
}
main(){
freopen("c575.txt", "r", stdin);
cin >>n >>k;
for (int i = 0; i < n; i++){
cin>> point[i];
}
sort(point, point+n);
for (int i = 0; i < n; i++){
cout<< point[i] << " ";
}
cout << endl;
max_distance = point[n-1] - point[0];
for (int i = 1; i <= max_distance; i ++){
cout << "distance "<< i <<":" <<cover(i)<<endl;
}
return 0;
}
** 注意,以上程式並不是直接算出答案,老師只是讓大家看怎麼解答。
從以上的計算可以看到1個基地台的最小直徑是7,2個基地台的最小直徑是3,3個基地台的最小直徑是1。
5 2 5 1 2 81 60
從以上的例子就會發現,當服務點跟服務點的距離比較遠的話,裡面就多很多沒必要的計算,這時候,就可以利用二元搜尋來節省計算的時間了! 想想看怎麼利用二元搜尋~
第三子題的座標範圍不超過1,000,000,000,整數的範圍是-2,147,483,648(-2$^{31}$) 至 2,147,483,647,所以,可以利用整數儲存。但是,因為測資數量很大,不使用二元搜尋可能就會超過時間上限(TLE)~
要記得使用結構,這樣w跟f才會一起移動,否則會算錯~
範例2排序後的結果是
5 3 4 2 3 1