判断抽签能否成功
?
/*************************************************************************> File Name: 163.cpp> Author: > Mail: > Created Time: 2015年11月11日 星期三 13時55分16秒************************************************************************/#include <iostream> #include <algorithm> #include <vector>using namespace std;/*output the vector data*/ struct myclass{void operator() (int i){cout << i << " ";} }myobject;/*recursion二分遞歸查找*/ int binary_search_recursion(const vector<int> &v, int low, int high, int goal) {if (low <= high){int middle = (low + high) / 2;if (goal == v[middle])return middle;else if (goal > v[middle])binary_search_recursion(v, middle+1, high, goal);elsebinary_search_recursion(v, low, middle-1, goal);}else return -1; }void input_data(int *n, int *m, vector<int> &k) {int val;cout << "n = ";cin >> *n;cout << "m = ";cin >> *m;cout << "k = {";for (int i = 0; i < *n; i++){cin >> val;k.push_back(val);cin.get();cin.get();} } /*暴力枚舉*/ void solve_1(int n, int m, const vector<int> &k) {for (int a = 0; a < n; a++)for (int b = 0; b < n; b++)for (int c = 0; c < n; c++)for (int d = 0; d < n; d++){if (k[a] + k[b] + k[c] + k[d] == m){cout << "Yes" << endl;return;}}cout << "No" << endl;return; }/*N^3*O(longN)*/ void solve_2(int n, int m, const vector<int> &k) {for (int a = 0; a < n; a++)for (int b = 0; b < n; b++)for (int c = 0; c < n; c++){if (binary_search_recursion(k, 0, k.size()-1, m-k[a]-k[b]-k[c]) != -1){cout << "Yes" << endl;return;}}cout << "No" << endl;return; }/*N^2*O(longN)*/ void solve_3(int n, int m, const vector<int> &k) {vector<int> k34;for (int i = 0; i < n; i++)for (int j = 0; j < n; j++)k34.push_back(k[i] + k[j]);sort(k34.begin(), k34.end());for (int i = 0; i < n; i++)for (int j = 0; j < n; j++){if (binary_search_recursion(k34, 0, k34.size()-1, m-k[i]+k[j]) != -1){cout << "Yes" << endl;return;}}cout << "No" << endl;return; }int main() {int n = 0, m = 0;vector<int> k;input_data(&n, &m, k);solve_1(n, m, k);sort(k.begin(), k.end());solve_2(n, m, k);solve_3(n, m, k);return 0; }第一種解法:枚舉法,將四次的所有的可能取值相加,如果等于m,則輸出Yes,否則輸出No;這個解法很簡單,四個嵌套的for循環很簡單就可以實現;但是時間復雜度太高,O(N^4),如果N的值比較大,那么這個程序會很耗時間;
第二種解法:目的就是為了降低時間復雜度,所以只能對那四個for循環下手,所以思路------就是減少for循環的個數;
在最后一個for循環中判斷k[a]+k[b]+k[c]+k[d] == m;其實也就是在這個數組中判斷是不是存在k[d] == m-k[a]-k[b]-k[c];
所以最后一個循環就可以改變為對一個數值(m-k[a]-k[b]-k[c])進行查找,如果這里用普通的查找,時間復雜度是O(N),那么整體的時間復雜度是N^3O(N),那么時間復雜度沒有下降;
所以用簡單的二叉查找(如果要用二叉查找,那么必須要提前對數組進行排序,排序的時間復雜度為最差的是O(N^2)),二叉查找的時間復雜度是O(logN);那么該解決方法的總的時間復雜度是 O(N^2)+N^3O(logN),也就是N^3O(logN);
第三種解法:因為第二種的時間復雜度還是比較高;所以我們還要對其進行減小;但是入手處在哪里????當然還是for循環;
我們再減少一個for循環,讓第二個for循環里面進行判斷 m-k[a]+k[b] == k[c]+k[d];
所以我們必須提前將k[c]+k[d]所有的情況的取值存儲在一個數組kk中(必須排序,時間復雜度為N^2O(logN)),在第二個for循環里面在數組kk中二叉查找m-k[a]+k[b],二叉查找的時間復雜度是O(logN);
所以整體的時間復雜度是N^2O(logN)+N^2O(logN),也就是N^2O(logN);等于排序的時間復雜度加上for循環的時間復雜度;
轉載于:https://www.cnblogs.com/yxk529188712/p/4956414.html
總結
- 上一篇: Codeforces Round #32
- 下一篇: 通过url 下载文件