基础算法--数组配对

基础算法–数组配对

Description
数组配对任务描述:给你一个长度为n的数组A和一个正整数k,问从数组中任选两个数使其和是k的倍数,有多少种选法对于数组a1=1,a2=2,a3=2而言:(a1,a2)和(a2,a1)被认为是同一种选法

Input
输入n,k,n<=1000000,k<=1000,第二行有n个整数,大小不超过1e9

Output
输出符合题意的选法个数

很容易想到两个for循环,然后i和j相加取余,但是这样时间复杂度太大

根据((i%k)+(j%k))%k=0这个公式,我们可以想到,先把数组中的数组进行取余然后计算相同余数的个数,存放在另一个数组中。

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

在主函数中,我们可以只用1层for循环,我们可以使用i来表示j这里的i和j都是代表的存放余数数组的下标,j=(k-i)%k,这里的i是之前的一个数%k后的值,我们要求另一个数,根据((i%k)+(j%k))%k=0这个公式,另一个数必须要和i相加等于0。
我们可以换个方式理解j=(k-i)%k,i和j都是一个数同k取余后的结果,我们要这两个相加后再取余k还等于0,那么我们已知了i,所以j就可以求出来了,至于为什么后面还要跟一个%k,是因为有余数等于0的情况,而k-0=k不符合题意

注意最后结果还要用long long

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <math.h>
#include <string.h>
#include <string>
#include <stack>
#include <queue>
#include <map>

using namespace std;
const int inf=0x3f3f3f3f;
const int MAX=1e6+5;
int a[MAX];
/*
	数组配对
	从数组中任意选择两个数,求其是k的倍数的配对有多少组 
*/
int main()
{
	int n,k;
	while(~(scanf("%d%d",&n,&k)))
	{
		long long sum=0;
		memset(a,0,sizeof(a));
		for(int i=0;i<n;i++)
		{
			int t;
			scanf("%d",&t);
			a[t%k]++;
		}
		int j=0;
		for(int i=0;i<k;i++)
		{
			j=(k-i)%k;
			if(j<i)	continue;
			if(j==i)
			sum+=(long long)a[i]*a[i]-1/2;
			else
			sum+=(long long)a[i]*a[j];
		}
		printf("%lld\n",sum);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值