1.第K个数
思路:
代码:
1. #include<iostream> 2. using namespace std; 3. const int N = 10010; 4. int n, k; 5. int q[N]; 6. 7. int quick_sort(int l, int r, int k) { 8. if (l >= r) { 9. return q[l]; 10. } 11. int i = l - 1, j = r + 1,x=q[l+r>>1]; 12. while (i < j) { 13. do { 14. i++; 15. } while (q[i] < x); 16. do{ 17. j--; 18. }while (q[j] > x); 19. if (i < j) { 20. swap(q[i], q[j]); 21. } 22. } 23. int sl = j - l + 1; 24. if (k<=sl) { 25. //递归左区间 26. return quick_sort(l, j, k); 27. } 28. return quick_sort(j + 1, r, k-sl); 29. } 30. 31. int main(void) { 32. cin >> n >> k; 33. for (int i = 0; i < n; i++) { 34. cin >> q[i]; 35. } 36. cout << quick_sort(0, n - 1, k) << endl; 37. return 0; 38. }
2.逆序对个数
思路:
mid就是分界点
代码:
1. #include<iostream> 2. using namespace std; 3. const int N = 100010; 4. int q[N], tmp[N]; 5. int n; 6. 7. long long merge_sort(int l, int r) { 8. if (l >= r) { 9. return 0; 10. } 11. int mid = l + r >> 1; 12. long long res = merge_sort(l, mid) + merge_sort(mid + 1, r); 13. 14. int k = 0, i = l, j = mid + 1; 15. while (i <= mid && j <= r) { 16. if (q[i] <= q[j]) { 17. tmp[k++] = q[i++]; 18. } 19. else { 20. tmp[k++] = q[j++]; 21. res += mid - i + 1; 22. } 23. } 24. while (i <= mid) { 25. tmp[k++] = q[i++]; 26. } 27. while (j <= r) { 28. tmp[k++] = q[j++]; 29. } 30. for (int i = l, j = 0; i <= r; i++, j++) { 31. q[i] = tmp[j]; 32. } 33. return res; 34. } 35. //6 36. //2 3 4 5 6 1 37. int main(void) { 38. cin >> n; 39. for (int i = 0; i < n; i++) { 40. cin >> q[i]; 41. } 42. cout << merge_sort(0, n - 1) << endl; 43. return 0; 44. }
3.数的三次方根
很普通的一道二分查找,直接贴代码:
1. #include<iostream> 2. using namespace std; 3. #define eps 1e-8 4. int main(void) { 5. double x; 6. cin >> x; 7. double l = -10000, r = 100000; 8. while (r - l > eps) { 9. double mid = (l + r) / 2; 10. if (mid * mid * mid >= x) { 11. r = mid; 12. } 13. else { 14. l = mid; 15. } 16. } 17. printf("%lf", l); 18. return 0; 19. }
4.前缀和
代码:
1. #include<iostream> 2. using namespace std; 3. 4. const int N = 100010; 5. int n,m; 6. int a[N], s[N]; 7. 8. int main(void) { 9. cin >> n >> m; 10. for (int i = 1; i <= n; i++) { 11. cin >> a[i]; 12. } 13. //求前缀和 14. for (int i = 1; i <= n; i++) { 15. s[i] = s[i - 1] + a[i]; 16. } 17. while (m--) { 18. int l, r; 19. cin >> l >> r; 20. cout << s[r] - s[l - 1] << endl; 21. } 22. return 0; 23. }
5.子矩阵之和(二维前缀和)
直接套公式,代码:
1. #include<iostream> 2. using namespace std; 3. const int N = 1010; 4. int a[N][N], s[N][N]; 5. int n, m, q; 6. 7. int main(void) { 8. scanf("%d %d %d", &n, &m, &q); 9. for (int i = 1; i <= n; i++) { 10. for (int j = 1; j <= m; j++) { 11. scanf("%d", &a[i][j]); 12. } 13. } 14. //初始化前缀和 15. for (int i = 1; i <= n; i++) { 16. for (int j = 1; j <= m; j++) { 17. s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j]; 18. } 19. } 20. while (q--) { 21. int x1, y1, x2, y2; 22. scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 23. printf("%d\n", s[x2][y2] - s[x1 - 1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]); 24. } 25. return 0; 26. }
6.差分
差分就是前缀和的逆运算
代码:
1. #include<iostream> 2. using namespace std; 3. const int N = 10010; 4. int n, m; 5. int a[N], b[N]; 6. 7. void insert(int l, int r, int c) { 8. b[l] += c; 9. b[r + 1] -= c; 10. } 11. 12. int main(void) { 13. scanf("%d %d", &n, &m); 14. for (int i = 1; i <= n; i++) { 15. scanf("%d", &a[i]); 16. } 17. //构造差分数组 18. for (int i = 1; i <= n; i++) { 19. insert(i, i, a[i]); 20. } 21. while (m--) { 22. int l, r, c; 23. scanf("%d %d %d", &l, &r, &c); 24. insert(l, r, c); 25. } 26. //求出对区间操作之后的前缀和 27. for (int i = 1; i <= n; i++) { 28. a[i] = a[i - 1] + b[i]; 29. } 30. for (int i = 1; i <= n; i++) { 31. printf("%d ", a[i]); 32. } 33. return 0; 34. }
7.差分矩阵
1. #include<iostream> 2. using namespace std; 3. const int N = 1010; 4. int a[N][N], b[N][N]; 5. int n, m, q; 6. 7. void insert(int x1, int y1, int x2, int y2, int c) { 8. b[x1][y1] += c; 9. b[x1][y2+1] -= c; 10. b[x2+1][y1] -= c; 11. b[x2 + 1][y2 + 1] += c; 12. } 13. 14. int main(void) { 15. scanf("%d%d%d", &n, &m, &q); 16. for (int i = 1; i <= n; i++) { 17. for (int j = 1; j <= m; j++) { 18. scanf("%d", &a[i][j]); 19. } 20. } 21. //构造差分数组 22. for (int i = 1; i <= n; i++) { 23. for (int j = 1; j <= m; j++) { 24. insert(i, j, i, j, a[i][j]); 25. } 26. } 27. while (q--) { 28. int x1, x2, y1, y2,c; 29. scanf("%d %d %d %d %d", &x1, &y1, &x2, &y2, &c); 30. insert(x1, y1, x2, y2, c); 31. } 32. for (int i = 1; i <= n; i++) { 33. for (int j = 1; j <= m; j++) { 34. a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + b[i][j]; 35. } 36. } 37. for (int i = 1; i <= n; i++) { 38. for (int j = 1; j <= m; j++) { 39. printf("%d ", a[i][j]); 40. } 41. printf("\n"); 42. } 43. return 0; 44. }