算法——数组配对问题

解题思路:

1. 两重嵌套

按序取出一个数,查找其后面能否相加被k整除

2.数学组合法:

把数挨个对k进行取余后看做小球,放入a[0]~a[k-1]的小桶里,如果t%k==0,那么a[0]小桶里的数任意组合即可,然后查找像a[1]与a[k-1]这类相加等于K的小桶,对里面的球进行组

法一:

此算法较简单,但时间复杂度高

 

#include <stdio.h>

int main()
{
    int n, k;
    scanf("%d%d", &n, &k); // 读入序列长度 n 和取余数 k
    int a[n]; // 定义一个数组 a,存储原始序列
    int cnt = 0; // 记录能够被 k 整除的数对数量
    int i, j; // 循环变量
    for(i = 0; i < n; i++) // 读入整个序列
    {
        scanf("%d", &a[i]);
    }
    for(i = 0; i < n; i++) // 枚举第一个数
    {
        for(j = i + 1; j < n; j++) // 枚举第二个数
        {
            if((a[i] + a[j]) % k == 0) // 如果两数之和能被 k 整除,就计数
            {
                cnt++;
            }
        }
    }
    printf("%d\n", cnt); // 输出所求答案
    return 0; // 程序结束
}

 小编在这里提供第二种思路:(好的想法评论区见呐)

(想来想去,觉得小桶的说法会形象一点)

#include <stdio.h>
#define ll long long // 定义 long long 类型
int n, k;
int a[100000]; // 全局变量

void wyf1()
{
    memset(a, 0, sizeof(a)); // 清空数组 a
    scanf("%d%d", &n, &k);
    int i, t;
    for(i = 0; i < n; i++)
    {
        scanf("%d", &t);
        a[t % k]++; // 按照余数分类记数
    }
}

void wyf2()
{
    ll ans = 0; // 记录可组合的数的个数
    int i, j;
    for(i = 0; i < k; i++)
    {
        j = (k - i) % k; // i与j相加等于k
        if(j < i) // j < i,说明已经计算过
            break;
        else if(j == i) // j == i 时,计算可组合的数目
            ans += 1ll * a[i] * (a[i] - 1) / 2; // a[0]小桶里球的组合;
        else // 下标相加为k的情况
            ans += 1ll * a[i] * a[j];
    }
    printf("%lld\n", ans); // 注意输出的数据类型是 long long
}

int main()
{
    wyf1(); // 读入数据
    wyf2(); // 计算并输出结果
    return 0;
}

如果你不看完小编辛苦码的字,小编会很生气的 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值