解题思路

拿部分分思维:直接按照规矩,两两相乘再相加:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn = 200005;
  4. int n;
  5. int arr[maxn];
  6. long long result = 0;
  7. int main() {
  8. // 给数据io加速
  9. ios::sync_with_stdio(false);
  10. cin.tie(0);
  11. cout.tie(0);
  12. // 输入数据
  13. cin>>n;
  14. for(int i = 0; i < n; i++) {
  15. cin>>arr[i];
  16. }
  17. // 计算数据
  18. for(int i = 0; i < n; i++) {
  19. for(int j = i+1; j< n; j++) {
  20. result += (arr[i]*arr[j]);
  21. }
  22. }
  23. // 输出结果
  24. cout<<result<<endl;
  25. }

在计算数据中直接粗暴相乘并且相加,很显然时间复杂度过高,O(n^2),导致只能拿下30%的分数。

改进方法

观察公式:
result = a1a2 + a1a3 + a1a4 + a2a3 + a2a4 + a3a4
对每一项可以提取公因式变为:
result = a1(a2+a3+a4) + a2(a3+a4) + a3*(a4)
可以发现规律为:每一项乘与该项右侧的余项相加,于是可以想到用记忆化的思维存储右边的部分,时间复杂度变为O(n),通过一个数组mem存储,并且逆向记忆从an到an+an-1+……+a1的过程;

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int maxn = 200005;
  4. int n;
  5. long long arr[maxn];
  6. long long result;
  7. long long mem[maxn];
  8. int main() {
  9. // 给数据io加速
  10. ios::sync_with_stdio(false);
  11. cin.tie(0);
  12. cout.tie(0);
  13. // 初始化数据
  14. memset(arr, 0, sizeof(arr));
  15. memset(mem, 0, sizeof(mem));
  16. result = 0;
  17. // 输入数据
  18. cin>>n;
  19. for(int i = 1; i <= n; i++) {
  20. cin>>arr[i];
  21. }
  22. // 倒序-记忆化存储(a1+a2+a3...+an)
  23. mem[n] = arr[n];
  24. for(int i = n-1; i >= 0; i--) {
  25. mem[i] = arr[i] + mem[i+1];
  26. }
  27. for(int i = 1; i <= n-1; i++) {
  28. result += (arr[i] * mem[i+1]);
  29. }
  30. // 输出结果
  31. cout<<result<<endl;
  32. }

特别注意:第11行请使用long,只用int会炸。

点赞(0)
 

0 分

0 人评分

 

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

评论列表 共有 0 条评论

暂无评论