【算法导论(第三版)】第二章部分习题代码
2014-10-02 08:52
423 查看
【练习】
2.3-2 MERGE的改进
2.3-5 二分查找的C++代码
*2.3-7 (这道题其实有O(n)的算法,而且写起来更方便些)这里是O(nlogn)的算法
O(nlogn)算法思想:1.首先进行排序;2.然后枚举每一个小于等于x/2的数S[i],二分查找对应的x-S[i]是否存在
O(n)的方法是在数的范围不是特别大的时候(或者数的范围比较大,此时采用hash的方法)标记的方法,这里假设数的范围<=10000,并且假设数没有重复的情况下,其他情况稍许改变一下就行:
2-4(逆序对):这道题就是在归并排序中得到逆序对,具体见代码:
2.3-2 MERGE的改进
void MERGE(int *A, int p,int q, int r) { int B[maxn] , i = p , j = q+1 , k = 0; while(k < r - p + 1) { if(i > q || j <= r && A[i] > A[j]) B[k++] = A[j++]; else B[k++] = A[i++]; } for(i=0;i<r-p+1;i++) A[p+i] = B[i]; }
2.3-5 二分查找的C++代码
int find(int *a, int l, int r, int value) { if(l == r) return l; int mid = (l+r) >> 1; if(a[mid] >= value) return find(a, l, mid, value); else return find(a , mid+1, r , value); }
*2.3-7 (这道题其实有O(n)的算法,而且写起来更方便些)这里是O(nlogn)的算法
O(nlogn)算法思想:1.首先进行排序;2.然后枚举每一个小于等于x/2的数S[i],二分查找对应的x-S[i]是否存在
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1010; bool findx(int *S,int n, int x,int l,int r) { if(l > r) return false; if(l ==r) return S[l] == x; int mid = (l+r) >> 1; if(S[mid] >= x) return findx(S, n, x, l, mid); else return findx(S, n, x, mid+1, r); } bool check(int *S,int n,int x) { for(int i=0;S[i]<=x/2 && i < n;i++) { if(findx(S, n, x-S[i], i+1, n-1)) return true; } return false; } int main() { int S[1010] , x , n; while(~scanf("%d%d" , &n , &x)) { for(int i=0;i<n;i++) cin >> S[i]; if(check(S, n, x)) puts("yes"); else puts("no"); } return 0; }
O(n)的方法是在数的范围不是特别大的时候(或者数的范围比较大,此时采用hash的方法)标记的方法,这里假设数的范围<=10000,并且假设数没有重复的情况下,其他情况稍许改变一下就行:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1010; bool check(int *S,int n,int x) { bool vis[10001] = {0}; for(int i=0;i<n;i++) vis[x-S[i]] = true; for(int i=0;i<n;i++) if(vis[S[i]]) return true; return false; } int n ,x , S[maxn]; int main() { while(~scanf("%d%d" , &n , &x)) { for(int i=0;i<n;i++) cin >> S[i]; if(check(S, n, x)) puts("yes"); else puts("no"); } return 0; }
2-4(逆序对):这道题就是在归并排序中得到逆序对,具体见代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 1010; int ans; void merge_sort(int *A, int l,int r) { if(l >= r) return; int mid = (l+r) >> 1; merge_sort(A, l, mid); merge_sort(A, mid+1, r); int i = l , j = mid+1 ,B[maxn] , k = l; while(i <= mid || j <= r) { if(i > mid || j <= r && A[j] < A[i]) B[k++] = A[j++] , ans += mid-i+1; else B[k++] = A[i++]; } for(i=l;i<=r;i++) A[i] = B[i]; } int main() { int A[maxn] , n; while(~scanf("%d" , &n)) { for(int i=0;i<n;i++) cin >> A[i]; ans = 0; merge_sort(A, 0, n-1); cout << ans << endl; //for(int i=0;i<n;i++) cout << A[i] << " "; cout << endl; } return 0; }
相关文章推荐
- 【算法导论(第三版)】第四章部分习题代码
- 【算法导论】第三版课后习题2-4逆序对
- 算法导论第三版习题8.4
- 算法导论 6章堆排序的代码实现和部分课后练习
- 算法导论第六章习题答案(第三版) Introduction to Algorithm
- 算法导论第三版习题5.2
- 算法导论 python代码 第二章
- 算法导论第二版习题试解-第二章练习2.2
- 【算法导论】第三版课后习题*2.3-7
- 算法导论 第二章 循环不变式(loop invariant)
- 算法导论习题5.1-3
- 算法导论9.2-3习题解答(寻找第i小的数)
- 算法导论习题5.1-3
- 连连看的代码(基本算法)加了部分注释
- 算法导论6.3-3习题解答
- 【算法导论】0-1背包问题 与 部分背包
- 算法导论8.3-4习题解答(基数排序)
- 算法导论8.2-4习题解答(计数排序)
- 学会编辑代码——《狂人C》习题解答4(第二章习题7)
- 算法导论2-4习题解答(合并排序算法)