問題1
用來測試的,就不說了
問題2:中位數附近2k+1個數
給出一串整型數 a1,a2,...,an 以及一個較小的常數 k,找出這串數的中位數 m 和最接近 m 的小於等於 m 的 k 個數,以及最接近 m 的大於等於 m 的 k 個數。將這 2k+1 個數按升序排序后輸出。
中位數定義:如果數串的大小是偶數 2j,中位數是從小到大排列的第 j 個數;如果數串的大小是奇數 2j+1,中位數是從小到大排列的第 j+1 個數。
輸入
第一行是 k 的值和數串的長度 n。
第二行是以空格隔開的 n 個整型數,最后一個數后面有空格。
輸出
按升序排列的 2k+1 個數,以空格分開,最后一個數后面沒有空格。結果可能出現重復的數。
思路
這題如果直接排序再輸出是會超時的,排序算法的復雜度為nlgn,后來按照快排的思想做通過了。
先以快排的思想找出中位數,復雜度為n(遞歸方程為T(n)=T(n/2)+n,用代入法就可以證明),(由於快排是隨機選取一個數做標准,所以我們在排完一次后需要判斷所選標准和中位數的差距,接着在子區間內繼續尋找中位數,選取到中位數后返回,具體看searchmid函數,應該寫得很簡潔了)
按照快排的思想,我們已經將數組分為小於中位數的區間,中位數,大於中位數的區間。根據題目,所給的k很小,再根據選擇排序的思想在左右兩區間各選取k個數即可。

#include <iostream> #include <vector> #include <algorithm> #include <limits.h> using namespace std; //使用快速排序的思路,找出中間數,first和last為區間,pos為要尋找有序狀態下的第幾個數 int searchmid(vector<int>& v,int first, int last, int pos) { int left = first; int key = last; for (int i = first; i <= last; ++i) { if (v[i] < v[key]) { swap(v[i], v[left]); left++; } } swap(v[left], v[key]); if (left < pos) return searchmid(v, left+1, last, pos); else if (left > pos) return searchmid(v,first,left-1,pos); return left; } int main() { int k,length; cin >> k; cin >> length; vector<int> v(length,0); int pos = 0, num; while (cin >> num) { v[pos] = num; pos++; } /*int k = 0; vector<int> v = {34, 10,9,8,7,6,5,4,3,2,1,0}; int length = v.size();*/ vector<int> result; int index = searchmid(v, 0, length-1, length/2 - 1 + length%2); //在數組前一部分尋找k個小於等於v[index]的數 for (int j = 0; j < k; ++j) { int max = INT_MIN; int max_pos; for (int i = 0; i < index-j; ++i) { if (v[i] > max) { max = v[i]; max_pos = i; } } swap(v[max_pos],v[index-j-1]); } //在數組后一部分尋找k個大於等於v[index]的數 for (int j = 0; j < k; ++j) { int min = INT_MAX; int min_pos; for (int i = index + j + 1; i < length; ++i) { if (v[i] < min) { min = v[i]; min_pos = i; } } swap(v[min_pos],v[index+j+1]); } for (int i = index - k; i <= index + k; i++) { cout << v[i] ; if (i != index + k) cout << " "; } /*cout << endl; sort(v.begin(), v.end()); for (auto h : v) cout << h << " "; cout << endl; system("pause");*/ return 0; }
問題3:任意兩數之和是否等於給定數
題目描述
給定一個 int 數組 arr,元素按照升序排列且各不相同。另外有一個目標數 c,請你找出 arr 中所有的數對 a, b,使得 a + b = c。
輸入
輸入為三行,第一行為 arr 的元素個數,第二行為 arr,元素以空格分隔,第三行為目標數 c。
輸出
所有符合條件的數對 a, b。a 和 b 以空格分開,每個數對占據一行。每行中 a < b,所有數對以它的第一個數(也就是 a 的值)升序排列。
思路
直接遍歷判斷,符合條件的直接輸出就可以了。

int main() { int length; int target; cin >> length; vector<int> v(length, 0); for (int i = 0; i < length; ++i) cin >> v[i]; cin >> target; for (int i = 0; i < length;++i) { for (int j = i + 1; j < length; j++) { if (v[i] + v[j] == target) { cout << v[i]; cout << " "; cout << v[j]; cout << endl; } } } //system("pause"); return 0; }