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

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//两两相乘加和结果

 

posted @   Johnson-Hugo  阅读(183)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
点击右上角即可分享
微信分享提示