1.暴力解法:两个for循环,不再赘述
2.二分法:①:a1,a2,a3,a4两两相乘可化简为(a1+a2)*(a3+a4)+a1*a2+a3*a4。②:a1,a2,a3,a4,a5,a6,a7,a8两两相乘可化简为(a1+a2+a3+a4)*(a5+a6+a7+a8)+(a1+a2)*(a3+a4)+(a5+a6)*(a7+a8)+a1*a2+a3*a4+a5*a6+a7*a8。易推知对一串数量为N的数组亦可利用此种二分策略。
代码如下:
1 #include <stdio.h>
2 #include <math.h>
3 #define ll long long
4 ll N;
5 ll ans=0;
6 int n[300000];
7 ll Binary (ll start,ll end){
8 ll med = (start+end)/2;
9 if (end-start+1>3){
10 ll n1=Binary(start,med);
11 ll n2=Binary(med+1,end);
12 ans+=n1*n2;
13 return n1+n2;
14 }
15 //分为1、2、3三种状况分别处理,返回和值即可
16 if (end-start+1==3){
17 ans+=n[start]*n[start+1]+n[start]*n[start+2]+n[start+1]*n[start+2];
18 return n[start]+n[start+1]+n[start+2];
19 }
20 if (end-start+1==2){
21 ans+=n[start]*n[start+1];
22 return n[start]+n[start+1];
23 }
24 if (end-start+1==1){
25 ans+=n[start];
26 return n[start];
27 }
28 }
29 int main(){
30 scanf("%d",&N);
31 for (ll i=1;i<=N;i++){
32 scanf("%d",&n[i]);
33 }
34 ll s1=Binary (1,N);
35 printf("%d",ans);
36 return 0;
37 }
三、前缀和
观察得知a1,a2,a3,a4两两相乘可化简为a1*(a4+a3+a2)+a2*(a4+a3)+a3*(a4),可利用前缀和性质求解
代码如下:
1 #include<bits/stdc++.h>
2 using namespace std;
3 int main()
4 {
5 int n;
6 cin>>n;
7 long long Sum[n];
8 int sum=0,k[n];
9 for(int i=0;i<n;i++)
10 {
11 cin>>k[i];
12 sum+=k[i];
13 Sum[i]=sum;
14 }
15 long long ans=0;
16 for(int i=0;i<n;i++)
17 {
18 ans+=(Sum[n-1]-Sum[i])*k[i];
19 }
20 cout<<ans;
21 }
输入格式:
4//数字个数
1 2 3 4//数组
输出:
35//两两相乘加和结果