蓝桥杯-求和问题

举报
别团等shy哥发育 发表于 2023/04/04 22:56:36 2023/04/04
【摘要】 @toc 1、问题描述给定 n 个整数 a1,a2,...,ana_1,a_2,...,a_na1​,a2​,...,an​,求它们两两相乘再相加的和,即:S=a1.a2+a1.a3+...+a1.an+a2.a3+...+an−2.an−1++an−2.an+an−1.anS=a_1.a_2+a_1.a_3+...+a_1.a_n+a_2.a_3+...+a_{n-2}.a_{n-1}++...

@toc

1、问题描述

给定 n 个整数 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n ,求它们两两相乘再相加的和,即:

S = a 1 . a 2 + a 1 . a 3 + . . . + a 1 . a n + a 2 . a 3 + . . . + a n 2 . a n 1 + + a n 2 . a n + a n 1 . a n S=a_1.a_2+a_1.a_3+...+a_1.a_n+a_2.a_3+...+a_{n-2}.a_{n-1}++a_{n-2}.a_{n}+a_{n-1}.a_n

输入格式

输入的第一行包含一个整数 n

第二行包含 n 个整数 a 1 , a 2 , . . . , a n a_1,a_2,...,a_n

输出格式

输出一个整数 S,表示所求的和。请使用合适的数据类型进行运算。

样例输入

4
1 3 6 9

样例输出

117

评测用例规模与约定

对于 30% 的数据,1≤n≤1000,1≤ a i a_i ≤100 。

对于所有测评用例,1≤n≤200000,1≤ a i a_i ≤1000。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 512M

2、解法一:暴力解法(两层循环)

我们直接两个for循环就可以解决,每次遍历到某个数的额时候,让它与自己后面的所有数字相乘并求和即可。

以样例做个循环分析如下:

  • i=0,j=1,2,3
  • i=1,j=2,3
  • i=2,j=3

代码如下:

// //暴力解法,这种会超时。
public static void sum1(){
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    int[] arr = new int[n];
    long sum=0;
    for (int i = 0; i < n; i++) {
        int temp = scanner.nextInt();
        arr[i]=temp;
    }
    for (int i = 0; i < arr.length; i++) {
        for (int j =i+1; j <arr.length ; j++) {
            sum+=arr[i]*arr[j];
        }
    }
    System.out.println(sum);
    scanner.close();
}

运行结果如下:

image-20230225195126100

这种会超时,看下面这种优化后的。

3、解法二:结合律(一层循环解决)

根据结合律化简求和公式如下所示:

\begin{align} S & = a_1.a_2+a_1.a_3+...+a_1.a_n+a_2.a_3+...+a_{n-2}.a_{n-1}++a_{n-2}.a_{n}a_{n-1}.a_n \\ & = a_1(a_2+a_3+...+a_n)+a_2(a_3+...+a_n)+...+a_{n-2}(a_{n-1}+a_{n})+a_{n-1}.a_n \end{align}

如果输入为1 3 6 9

第一次两两相乘为1*3+1*6+1*9=1*(3+6+9)
第二次两两相乘为3*6+3*9=3*(+6+9)
第三次两两相乘为6*9=6*(9)
最后相加,即每一次该数乘以sum内不包含本身的值

代码如下所示:

public static void sum2(){
    Scanner scanner = new Scanner(System.in);
    int n = scanner.nextInt();
    int[] arr = new int[n];
    long sum=0;
    long result=0;
    for (int i = 0; i < n; i++) {
        arr[i] = scanner.nextInt();
        sum+=arr[i];  //直接刚开始就对数组求和
    }
    for (int i = 0; i <n; i++) {
        sum=sum-arr[i];
        result+=arr[i]*sum;
    }
    System.out.println(result);
}

image-20230225195801611

这里sum必须用long类型,要不会超出int范围

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。