学习随笔——求任意两数乘积和

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//两两相乘加和结果
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值