当前位置:   article > 正文

分治法进阶练习

分治法进阶练习

第1关:线性时间选择问题

  1. #include <iostream>
  2. using namespace std;
  3. void Swap(int &a,int &b)
  4. {//交换函数
  5. /*********begin************/
  6. int c;
  7. c = a;
  8. a = b;
  9. b = c;
  10. /*********end************/
  11. }
  12. int Partition(int a[],int p,int r,int x)
  13. {//以x为基准划分函数
  14. /*********begin************/
  15. int i = p,j = r;
  16. while(i <= r && j >= p)
  17. {
  18. while(a[i] < x) i ++ ;
  19. while(a[j] > x) j -- ;
  20. if(i >= j) break;
  21. else
  22. {
  23. Swap(a[i],a[j]);
  24. i ++ ,j -- ;
  25. }
  26. }
  27. return j;
  28. /*********end************/
  29. }
  30. void BubbleSort(int a[],int p,int r)
  31. {//冒泡排序
  32. /*********begin************/
  33. for(int i = p;i < r;i ++ )
  34. {
  35. int k = i;
  36. for(int j = i + 1;j <= r;j ++ )
  37. if(a[j] < a[k])
  38. k = j;
  39. Swap(a[i],a[k]);
  40. }
  41. /*********end************/
  42. }
  43. int Select(int a[],int p,int r,int k)
  44. {
  45. /*********begin************/
  46. if(r - p < 75)
  47. {
  48. BubbleSort(a,p,r);
  49. return a[p + k - 1];
  50. }
  51. for (int i = 0; i <= (r - p - 4) / 5; i++)
  52. {
  53. BubbleSort(a,p + 5 * i, p + 5 * i + 4);
  54. int temp = a[p + 5 * i + 2];
  55. a[p + 5 * i + 2] = a[p + i];
  56. a[p + i] = temp;
  57. }
  58. int x = Select(a,p,p + (r - p - 4)/5,(r - p - 4)/10 + 1);
  59. int u = Partition(a,p,r,x);
  60. int v = u - p + 1;
  61. if(k == v) return a[u];
  62. else if(k < v) return Select(a,p,u,k);
  63. else return Select(a,u + 1,r,k - v);
  64. /*********end************/
  65. }

第2关:众数问题

  1. int getMode(int a[],int p,int r,int &Cnt)
  2. {
  3. int *num = new int [100];
  4. int maxv = 0;
  5. for(int i = p;i <= r;i ++ )
  6. {
  7. num[a[i]] ++ ;
  8. if(a[i] > maxv)
  9. maxv = a[i];
  10. }
  11. int idx = 0,t = 0;
  12. for(int i = 0;i <= maxv;i ++ )
  13. if(num[i] > t)
  14. {
  15. idx = i;
  16. t = num[i];
  17. }
  18. Cnt = t;
  19. return idx;
  20. }

第3关:求逆序对数

  1. //归并排序及求逆序对
  2. #include<iostream>
  3. using namespace std;
  4. #define N 1000005
  5. int a[N], b[N];//b为辅助数组
  6. long long cnt;
  7. void merge_sort(int l, int r)
  8. {
  9. // 如果整个区间中元素个数大于1,则继续分割
  10. if (r - l > 0)
  11. {
  12. // 1、尽量划分为数量相等的2个子序列,并排序
  13. int mid = (l + r) / 2;
  14. merge_sort(l, mid);
  15. merge_sort(mid + 1, r);
  16. // 2、将2个有序的序列合并成一个有序序列,在左右有序的子数组合并的同时,统计逆序对数
  17. /*********Begin***********/
  18. int i = l,j = mid + 1,k = l;
  19. while(i <= mid && j <= r)
  20. {
  21. if(a[i] <= a[j]) b[k ++ ] = a[i ++ ];
  22. else b[k ++ ] = a[j ++ ],cnt += mid - i + 1;
  23. }
  24. while(i <= mid) b[k ++ ] = a[i ++ ];
  25. while(j <= r) b[k ++ ] = a[j ++ ];
  26. /*********End***********/
  27. // 3、将辅助数组b中排好序的元素复制到a中
  28. for (i = l; i <= r; i++)
  29. a[i] = b[i];
  30. }
  31. }
  32. int main()
  33. {
  34. int n;
  35. while (cin >> n)
  36. {
  37. for (int i = 1; i <= n; i++)
  38. cin >> a[i];
  39. cnt = 0;
  40. merge_sort(1, n);
  41. cout << cnt << endl;
  42. }
  43. return 0;
  44. }

第4关:棋盘覆盖问题

  1. #include<iostream>
  2. #include<iomanip>
  3. # define SIZE 32
  4. using namespace std;
  5. int tile = 0;
  6. int Board[SIZE][SIZE];
  7. //棋盘以(tr,tc)为左上角,以size为边长,特殊方格位置在(dr,dc),ChessBoard函数用分治法
  8. //完成它四个子棋盘覆盖
  9. void ChessBoard(int tr, int tc, int dr, int dc, int size)
  10. {
  11. /************Begin**************/
  12. if (size == 1) return ;
  13. int t = tile ++;
  14. int s = size / 2;
  15. if (dr < tr + s && dc < tc + s)
  16. ChessBoard(tr,tc,dr,dc,s);
  17. else
  18. {
  19. Board[tr + s - 1][tc + s - 1] = t;
  20. ChessBoard(tr,tc,tr + s - 1,tc + s - 1,s);
  21. }
  22. if (dr < tr + s && dc >= tc + s)
  23. ChessBoard(tr,tc + s,dr,dc,s);
  24. else
  25. {
  26. Board[tr + s - 1][tc + s] = t;
  27. ChessBoard(tr,tc + s,tr + s - 1,tc + s,s);
  28. }
  29. if (dr >= tr + s && dc < tc + s)
  30. ChessBoard(tr + s,tc,dr,dc,s);
  31. else
  32. {
  33. Board[tr + s][tc + s - 1] = t;
  34. ChessBoard(tr + s,tc,tr + s,tc + s - 1,s);
  35. }
  36. if (dr >= tr + s && dc >= tc + s)
  37. ChessBoard(tr + s,tc + s,dr,dc,s);
  38. else
  39. {
  40. Board[tr + s][tc + s] = t;
  41. ChessBoard(tr + s,tc + s,tr + s,tc + s,s);
  42. }
  43. /************End**************/
  44. }
  45. int main()
  46. {
  47. /************Begin**************/
  48. int size,dr,dc;
  49. cin >> size >> dr >> dc;
  50. ChessBoard(0,0,dr,dc,size);
  51. Board[dr][dc] = -1;
  52. /************End**************/
  53. for (int i = 0; i < size; i++)
  54. {
  55. for (int j = 0; j < size; j++)
  56. cout << setw(4) << Board[i][j];
  57. cout << endl;
  58. }
  59. return 0;
  60. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/716326
推荐阅读
相关标签
  

闽ICP备14008679号