题目意思很明确
乍一看直接可以写代码了,直接双重for循环,但是该题全部样例是10^5,双重for循环则会导致超时
#include<iostream>
#include<vector>
#define int long long
using namespace std;
signed main()
{
int n,value,sum=0;
vector<int>v;
cin >> n;
for (int i = 0; i < n; i++) {
cin >> value;
v.push_back(value);
}
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
sum += (v[i] * v[j]);
}
}
cout << sum << endl;
return 0;
}
但是我们可以做一点优化就可以解决问题了,仔细观察问题我们不难发现,就是每一个数字都去乘以排在它后面的数后相加,那么我们不难发现其实可以利用一下乘法分配律
例如
4 1 3 6 9 原本的式子:1*3+1*6+1*9 + 3*6+3*9 + 6*9 分配律:1*(3+6+9)+ 3*(6+9)+6*9
这样我们的代码就变成了
#include<iostream> #include<vector> #define int long long using namespace std; signed main() { int n,value,sum=0,ans=0; vector<int>v; cin >> n; for (int i = 0; i < n; i++) { cin >> value; v.push_back(value); sum += value; } for (int i = 0; i < n; i++) { sum -= v[i]; ans += (v[i] * sum); } cout << ans << endl; return 0; }
也就不会超时了
其实也可以利用一下前缀和的思想
#include<iostream>
#include<vector>
#define int long long
using namespace std;
signed main()
{
int n, value, sum = 0, ans = 0;
vector<int>v,prefix;
cin >> n;
v.push_back(0);
prefix.push_back(0);
for (int i = 1; i <= n; i++) {
cin >> value;
v.push_back(value);
sum += value;
prefix.push_back(sum);//前缀和数组
}
for (int i = 1; i <= n; i++) {
ans += (v[i] *(prefix[n]-prefix[i]));
}
cout << ans << endl;
return 0;
}