Κοινή χρήση τεχνολογίας

Αλγόριθμος - άθροισμα προθέματος

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Πίνακας περιεχομένων

[Πρότυπο] Μονοδιάστατο άθροισμα προθέματος

[Πρότυπο] Δισδιάστατο άθροισμα προθέματος

Βρείτε το κεντρικό ευρετήριο ενός πίνακα

Προϊόν συστοιχιών εκτός από τον εαυτό

άθροισμα επιφανειών μήτρας


[Πρότυπο] Μονοδιάστατο άθροισμα προθέματος

Εάν χρησιμοποιήσουμε ένα διάλυμα ωμής βίας,Ο πίνακας πρέπει να διασχίζεται κάθε φορά, συνολικά q φορές,Έτσιχρονική πολυπλοκότηταείναι πολύ υψηλό, αυτή τη στιγμή κατασκευάζουμε έναν πίνακα αθροίσματος προθέματος στοΤο άθροισμα κάθε διαστήματος εντός του διαστήματος 1-n αποθηκεύεται στο , χρειάζεστε τα πρώτα n στοιχεία και άμεση πρόσβαση στο πρόθεμα dp και στη θέση δείκτη του πίνακα. ο κώδικας εμφανίζεται ως εξής:

  1. #include<iostream>
  2. #include<vector>
  3. using namespace std;
  4. int main()
  5. {
  6. // 读入数据
  7. int n, q; cin >> n >> q;
  8. // n + 1 添加了虚拟节点0
  9. vector<int> arr(n + 1); // 默认全部为0
  10. for (int i = 1; i <= n; i++)
  11. cin >> arr[i];
  12. // 预处理出一个前缀和数组
  13. vector<long long> dp(n + 1); // 防止溢出
  14. for (int i = 1; i <= n; i++)
  15. dp[i] = dp[i - 1] + arr[i];
  16. // 使用前缀和数组
  17. int l = 0, r = 0;
  18. while (q--)
  19. {
  20. cin >> l >> r;
  21. cout << dp[r] - dp[l - 1] << endl;
  22. }
  23. return 0;
  24. }

[Πρότυπο] Δισδιάστατο άθροισμα προθέματος

προεπεξεργασίαένας πίνακας αθροίσματος προθέματος που θαΤο άθροισμα όλων των στοιχείων από τις θέσεις (1, 1) έως (i, j).υπάρχει σε αυτόν τον πίνακα dp, μέσωΜέθοδος υπολογισμού επιφάνειας, για να βρείτε την τελική απάντηση, ο κωδικός είναι ο εξής:

  1. int main()
  2. {
  3. // 读入数据
  4. int n, m, q; cin >> n >> m >> q;
  5. vector<vector<int>> arr(n + 1, vector<int>(m + 1));
  6. for (int i = 1; i <= n; i++)
  7. for (int j = 1; j <= m; j++)
  8. cin >> arr[i][j];
  9. // 预处理一个前缀和数组
  10. vector<vector<long long>> dp(n + 1, vector<long long>(m + 1)); // 防止溢出
  11. for (int i = 1; i <= n; i++)
  12. for (int j = 1; j <= m; j++)
  13. dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + arr[i][j] - dp[i - 1][j - 1];
  14. // 使用前缀和数组
  15. while (q--)
  16. {
  17. int x1, y1, x2, y2; cin >> x1 >> y1 >> x2 >> y2;
  18. cout << dp[x2][y2] - dp[x2][y1 - 1] - dp[x1 - 1][y2] + dp[x1 - 1][y1 - 1] << endl;
  19. }
  20. return 0;
  21. }

Βρείτε το κεντρικό ευρετήριο ενός πίνακα

Σημειώστε τις ακραίες θήκες εδώΔεν χρειάζεται να ανοίξετε το πρόθεμα και τον πίνακα διαστήματος n+1, επειδή υπάρχει ένα στοιχείο στον αρχικό πίνακα που θα πρέπει να χρησιμοποιηθεί ως κεντρικός δείκτης αυτής της ερώτησης Ο κώδικας είναι ο εξής:

  1. class Solution {
  2. public:
  3. int pivotIndex(vector<int>& nums) {
  4. int n = nums.size();
  5. vector<int> f(n), g(n);
  6. // 预处理前缀和数组 从左向右
  7. for (int i = 1; i < n; i++)
  8. f[i] = f[i - 1] + nums[i - 1];
  9. // 预处理后缀和数组 从右向左
  10. for (int i = n - 2; i >= 0; i--)
  11. g[i] = g[i + 1] + nums[i + 1];
  12. for (int i = 0; i < n; i++)
  13. {
  14. if (g[i] == f[i])
  15. return i;
  16. }
  17. return -1;
  18. }
  19. };

Προϊόν συστοιχιών εκτός από τον εαυτό

Το νόημα είναι παρόμοιο με την προηγούμενη ερώτηση, αλλά πρέπει να σημειωθεί ότι οι οριακές περιπτώσεις f(0) και g(n-1) θα πρέπει να αρχικοποιηθούν σε 1 αντί για 0. Ο κώδικας είναι ο εξής:

  1. class Solution {
  2. public:
  3. vector<int> productExceptSelf(vector<int>& nums) {
  4. int n = nums.size();
  5. vector<int> f(n), g(n), ret(n);
  6. // 处理边界情况
  7. f[0] = 1; g[n - 1] = 1;
  8. // 预处理前缀积数组 从左向右
  9. for (int i = 1; i < n; i++)
  10. f[i] = f[i - 1] * nums[i - 1];
  11. // 预处理后缀积数组 从右向左
  12. for (int i = n - 2; i >= 0; i--)
  13. g[i] = g[i + 1] * nums[i + 1];
  14. for (int i = 0; i < n; i++)
  15. ret[i] = f[i] * g[i];
  16. return ret;
  17. }
  18. };

άθροισμα επιφανειών μήτρας

Σημείωση: Το δισδιάστατο πρόθεμα και ο πίνακας πρέπει να έχουν μία ακόμη σειρά και μία στήλη, διαφορετικά θα υπάρχει πρόσβαση εκτός ορίων. ans[ 0 ][ 0 ] αντιστοιχεί σε dp [ 1 ][ 1] αυτή τη θέση. ο κώδικας εμφανίζεται ως εξής:

  1. class Solution {
  2. public:
  3. vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k) {
  4. int m = mat.size(), n = mat[0].size(); // m 为行 n 为列
  5. // 预处理一个二维前缀和数组 dp
  6. vector<vector<int>> dp(m + 1, vector<int>(n + 1));
  7. for (int i = 1; i <= m; i++)
  8. for (int j = 1; j <= n; j++)
  9. dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + mat[i - 1][j - 1] - dp[i - 1][j - 1];
  10. // 存放答案的二维数组 ans
  11. vector<vector<int>> ans(m, vector<int>(n));
  12. for (int i = 0; i < m; i++)
  13. {
  14. for (int j = 0; j < n; j++)
  15. {
  16. int x1 = max(0, i - k) + 1, y1 = max(0, j - k) + 1;
  17. int x2 = min(m - 1, i + k) + 1, y2 = min(n - 1, j + k) + 1;
  18. ans[i][j] = dp[x2][y2] - dp[x1 - 1][y2] - dp[x2][y1 - 1] + dp[x1 - 1][y1 - 1];
  19. }
  20. }
  21. return ans;
  22. }
  23. };