每日新发现:遍历数组的新方式、新累加方式、新数组重置函数

        这几天做到一个题,题意是给两组数,每组求相加和,最后看看两组求出来的和相等的个数有几个。

        然后呢,我根据题意,就这么直接设计出来了这么一个东西:

#include <bits/stdc++.h>
using namespace std;
const int cxd = 5e5+5, mxn = 1e3+5;
int f[mxn], f1[cxd], g[mxn],g1[cxd];
int a, b, c, d, i, j, k, m, n, x, y, z;
long long sum;

signed main()
{
    scanf("%d", &n);
    while (n--)
    {
        scanf("%d%d", &a, &b);
        for (i = 1; i <= a; i++)  scanf("%d", f+i);  // 遍历
        for (i = 1; i <= b; i++)  scanf("%d", g+i);
        for (i = 1; i <= n-1; i++)
            for (j = i+1; j <= n; j++)  f1[f[i] + f[j]]++; // 再遍历
        for (i = 1; i <= n-1; i++)
            for (j = i+1; j <= n; j++)  g1[g[i] + g[j]]++;
        
    }
    return 0;
}

        然后我想要再遍历两个桶(f1和g1),然后感觉复杂度不太对劲,肯定是有什么地方我没想到,然后呢,我去瞄了一眼老师的答案,这个优化方式给我震惊了。因为是很简单的,但是之前没有这么优化过,就想发到博客上,当成日常记录一下,以便我以后复习的时候再看。这段代码是我用我的风格优化过的:

#include <bits/stdc++.h>
using namespace std;
const int cxd = 3e3+5, mxn = 5e5+5;
int f[cxd], g[mxn << 1];
int a, b, c, d, i, j, k, m, n, x, y, z;
long long sum;

signed main()
{
    scanf("%d", &n);
    while (n--){
        memset(g, 0, sizeof g);  //新学的函数:重置数组的方法
        sum = 0;
        scanf("%d%d", &a, &b);
        for (i = 1; i <= a; i++){
            scanf("%d", f+i);
            for (j = 1; j < i; j++)  g[f[i] + f[j]]++;  //这波直接把赋值和桶放到一块去我是真的没想到
        }
        for (i = 1; i <= b; i++){
            scanf("%d", f+i);
            for (j = 1; j < i; j++)  sum += g[f[i] + f[j]];  //总和算法,不用再跟冤种一样去遍历10的11次方复杂度的数组了,真的太妙了
        }
        printf("%lld\n", sum);  //我再次忘记了%lld,写成了%d(哭)
    }
    return 0;
}

        这整套流程下来可谓是简之又简啊,堪称赏心悦目(wu),总之,有四点内容:

        1,新学到一个重置数组的函数,memset函数,第一个数组名,第二个重置数,第三个sizeof 数组名

        2,赋值和桶放到一起操作,以及新的遍历方式,在每次读入数据时就把事情做完了,很合我心

        3,总和的新方式,当然和这题的答题方式有一定关系,先存有的,没有的直接是0, 然后第二组直接把第一组存的加上去,也不用怕重复,每次相加都是独立的,就这样得出了最后的总和,哪还需要麻烦得要死的二轮循环遍历呢?

        4,数组定义成long long我往往忘记,下次别这样啊要吃大亏。。

        总而言之,这是今天做的这道题的一些心得。前两天第一次尝试用哈希,也尝试了很久,但是暂时不打算写心得了。

        今天就到此结束吧,前两天熬夜有点晚,今天得好好睡个觉,晚安~

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值