当前位置:   article > 正文

算法与分析学习题目记录——分治法_最大子段和问题又叫最大子数列问题。该问题的目标是在一个数列中找到一个连续的子

最大子段和问题又叫最大子数列问题。该问题的目标是在一个数列中找到一个连续的子

目录

最大子段和

二分查找

最小差问题


最大子段和

题目描述

最大子段和问题又叫最大子数列问题。该问题的目标是在一个数列中找到一个连续的子数列,使该子数列的和最大。例如,对数列−2, 1, −3, 4, −1, 2, 1, −5, 4,其连续子数列中和最大的是4,−1, 2, 1,其和为6。

你的任务,就是对于给定的数列,求出其中的一个子数列使其和最大。

输入

有多组数据。每组数据有2行,第一行是一个整数n(0<=n<=100),表示数列的长度,第二行上有n个整数a1, a2, ..., an(-100<=ai<=100),其中至少数有一个非负。

输出

对每组测试数据,输出它的最大子段和值。

样例输入

6

-2 11 -4 13 -5 -2

8

4 -2 5 -1 5 6 -3 -50

样例输出

20

17

  1. #include <iostream>
  2. using namespace std;
  3. static long res[1000], number = 0;
  4. int remax(int A, int B, int C) {
  5. return A > B ? A > C ? A : C : B > C ? B : C;
  6. }
  7. long maxsum(int a[], int left, int right) {
  8. int i,j;
  9. long leftmax,rightmax;
  10. long mlb,lb;
  11. long mrb,rb;
  12. if (left == right) {
  13. if (a[left] > 0)
  14. return a[left];
  15. else
  16. return 0;
  17. }
  18. int mid = (left + right) / 2;
  19. leftmax = maxsum(a,left,mid);
  20. rightmax = maxsum(a,mid + 1,right);
  21. mlb = 0, lb = 0;
  22. for (i = mid; i >= left; i--)
  23. {
  24. lb += a[i];
  25. if (lb > mlb)
  26. mlb = lb;
  27. }
  28. mrb = 0,rb = 0;
  29. for (j = mid + 1; j <= right; j++)
  30. {
  31. rb += a[j];
  32. if (rb > mrb)
  33. mrb = rb;
  34. }
  35. return remax(leftmax,rightmax,mlb + mrb);
  36. }
  37. int main() {
  38. int n;
  39. while (cin >> n) {
  40. int* a = new int[n];
  41. for (int i = 0; i < n; i++)
  42. cin >> a[i];
  43. res[number] = maxsum(a, 0, n - 1);
  44. number++;
  45. delete[] a;
  46. }
  47. for (int i = 0; i < number; i++)
  48. cout << res[i] << endl;
  49. return 0;
  50. }

二分查找

题目描述

给定一列整数a1、a2、…、an,以及一个整数x,判定x是否在其中。

输入

一组数据由两行组成,第一行是两个正整数n,x。第二行有n个已排好序的整数a1、a2、…、an,整数之间用空格隔开。

输出

对输入的n个整数a1、a2、…、an,及x,如果x在其中出现,那么输出“place=”,接着输出数#,其中#是x在数列中的位置数(第1个数的位置是1);如果找不到,那么输出“Not found.”.

样例输入

4 9

1 5 6 9

4 15

2 10 20 21

样例输出

place=4

Not found.

  1. #include <iostream>
  2. using namespace std;
  3. static int res[1000], iffind[1000], number = 0;
  4. void kp(int a[], int i, int j) {
  5. if (i > j)
  6. return;
  7. int temp = a[i];
  8. int l = i;
  9. int r = j;
  10. while (i != j) {
  11. while (i < j && a[j] >= temp)
  12. {
  13. j--;
  14. }
  15. a[i] = a[j];
  16. while (i < j && a[i] <= temp)
  17. {
  18. i++;
  19. }
  20. a[j] = a[i];
  21. }
  22. a[i] = temp;
  23. kp(a, l, i - 1);
  24. kp(a, i + 1, r);
  25. }
  26. void findx(int a[], int low, int high, int x)
  27. {
  28. if (low > high) {
  29. iffind[number] = 0;
  30. return;
  31. }
  32. int mid = (low + high) / 2;
  33. if (a[mid] == x) {
  34. res[number] = mid + 1;
  35. iffind[number] = 1;
  36. }
  37. else if (a[mid] < x)
  38. findx(a, mid + 1, high, x);
  39. else
  40. findx(a, low, mid - 1, x);
  41. }
  42. int main() {
  43. int n, x;
  44. while (cin >> n) {
  45. cin >> x;
  46. int* a = new int[n];
  47. for (int i = 0; i < n; i++)
  48. cin >> a[i];
  49. kp(a, 0, n - 1);
  50. findx(a, 0, n - 1, x);
  51. number++;
  52. delete[] a;
  53. }
  54. for (int i = 0; i < number; i++) {
  55. if (iffind[i] == 1)
  56. cout << "place=" << res[i] << endl;
  57. else
  58. cout << "Not found." << endl;
  59. }
  60. return 0;
  61. }

最小差问题

题目描述

若给定两个数组(第一个是数组 A已经排好序,第二个是数组 B),在数组 A 中找 A[i],数组B中找B[j],使A[i]和B[j]两者的差取得最小。

编程求最小差。要求:时间复杂度 O(nlogn)。

输入

有多组测试数据,每组有3行。

每组的第1行是一个整数,(n<=10000)。接着有2行,每行上有个数为n的整数序列,分别表示数组A和B。

输出

对每组测试数据中的两个整数数组 A 和 B,输出所要求的最小差。

样例输入

4

3 4 6 7

2 3 8 9

样例输出

0

  1. #include <iostream>
  2. using namespace std;
  3. static int res[1000], iffind[1000], number = 0;
  4. void kp(int a[], int i, int j) {
  5. if (i > j)
  6. return;
  7. int temp = a[i];
  8. int l = i;
  9. int r = j;
  10. while (i != j) {
  11. while (i < j && a[j] >= temp)
  12. {
  13. j--;
  14. }
  15. a[i] = a[j];
  16. while (i < j && a[i] <= temp)
  17. {
  18. i++;
  19. }
  20. a[j] = a[i];
  21. }
  22. a[i] = temp;
  23. kp(a, l, i - 1);
  24. kp(a, i + 1, r);
  25. }
  26. int findmin(int a[], int b[],int n) {
  27. int res = 0, i = 0, j = 0;
  28. res = abs(a[0] - b[0]);
  29. while (i < n && j < n) {
  30. if (a[i] < b[j]) i++;
  31. else j++;
  32. if (i < n && j < n)
  33. res = min(res, abs(a[i] - b[j]));
  34. }
  35. return res;
  36. }
  37. int main() {
  38. int n, x;
  39. while (cin >> n) {
  40. int* a = new int[n];
  41. int* b = new int[n];
  42. for (int i = 0; i < n; i++)
  43. cin >> a[i];
  44. for (int i = 0; i < n; i++)
  45. cin >> b[i];
  46. kp(a, 0, n - 1);
  47. kp(b, 0, n - 1);
  48. res[number] = findmin(a, b, n);
  49. number++;
  50. delete[] a;
  51. delete[] b;
  52. }
  53. for (int i = 0; i < number; i++)
  54. cout << res[i] << endl;
  55. return 0;
  56. }

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

闽ICP备14008679号