LQ0014 求和思维

Posted 海岛Blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LQ0014 求和思维相关的知识,希望对你有一定的参考价值。

题目出处:蓝桥杯2022初赛

题目描述
给定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[2]·a[n]+…+a[n-1]·a[n]

输入格式
第一行为正整数n,第二行为n个整数。
30%的数据:2≤n≤1000,1≤a[i]≤100。
100%的数据:2≤n≤200000,1≤a[i]≤1000。

输出格式
输出一个数字表示答案S。

输入样例
4
1 3 6 9

输出样例
117

问题分析
用暴力法来解题会超时,参见最后一个代码。
一种解法是使用前缀和来计算,连存储数据的数组也不需要。
另外一种解法是根据公式来计算,其要点如下:
给定n个数,求部分两两相乘问题,需要找出其规律来,算起来就简单了。
先求出n个整数之和,再求出这n个整数的平方和,然后用公式算一下就好了。
具体的计算方法见程序代码。
求和后数会变得比较大,所以要用long long类型。

AC的解题代码(前缀和)如下:

/* LQ0014 求和 */

#include <stdio.h>

int main()

    int n, a;
    long long sum = 0, psum = 0;

    scanf("%d", &n);
    for (int i = 1; i <= n; i++) 
        scanf("%d", &a);
        sum += psum * a;
        psum += a;
    

    printf("%lld\\n", sum);

    return 0;

AC的解题代码(公式)如下:

/* LQ0014 求和 */

#include <stdio.h>

int main()

    int n, a;
    long long sum = 0, sum1 = 0;

    scanf("%d", &n);
    for (int i = 1; i <= n; i++) 
        scanf("%d", &a);
        sum += a;
        sum1 += a * a;
    

    printf("%lld\\n", (sum * sum - sum1) / 2);

    return 0;

超时的解题代码(暴力)如下:

/* LQ0014 求和 */

#include <stdio.h>

#define N 200000
int a[N];

int main()

    int n;
    long long sum = 0;

    scanf("%d", &n);
    for (int i = 0; i < n; i++)
        scanf("%d", &a[i]);

    for (int i = 0; i < n; i++)
        for (int j = i + 1; j < n; j++)
            sum += a[i] * a[j];

    printf("%lld\\n", sum);

    return 0;

以上是关于LQ0014 求和思维的主要内容,如果未能解决你的问题,请参考以下文章

LQ0031 生日蜡烛枚举

多数之和问题

多数之和问题

LQ0117 缩位求和进制

LQ0044 求和进制

LQ0046 凑算式枚举