Codeforces Round #544(Div. 3)--B Preparation for International Women's Day(简单思维题)

Preparation for International Women’s Day

time limit per test 2 seconds
memory limit per test 256 megabytes
题目链接https://codeforces.com/contest/1133/problem/B

International Women’s Day is coming soon! Polycarp is preparing for the holiday.

There are nn candy boxes in the shop for sale. The i-th box contains di candies.

Polycarp wants to prepare the maximum number of gifts for kk girls. Each gift will consist of exactly two boxes. The girls should be able to share each gift equally, so the total amount of candies in a gift (in a pair of boxes) should be divisible by kk. In other words, two boxes i and j (i≠j) can be combined as a gift if d i + d j di+dj is divisible by kk.

How many boxes will Polycarp be able to give? Of course, each box can be a part of no more than one gift. Polycarp cannot use boxes “partially” or redistribute candies between them.

在这里插入图片描述
Examples
input
7 2
1 2 2 3 2 4 10

output
6

input
8 2
1 2 2 3 2 4 6 10

output
8

input
7 3
1 2 2 3 2 4 5

output
4

Note
In the first example Polycarp can give the following pairs of boxes (pairs are presented by indices of corresponding boxes):

(2,3);
(5,6);
(1,4)
So the answer is 66.

In the second example Polycarp can give the following pairs of boxes (pairs are presented by indices of corresponding boxes):

(6,8);
(2,3);
(1,4);
(5,7).
So the answer is 88.

In the third example Polycarp can give the following pairs of boxes (pairs are presented by indices of corresponding boxes):

(1,2);
(6,7).
So the answer is 44.


题目的大意是这样的,给你一个数组代表第i个盒子的糖果,问你可以使用几个盒子,(盒子是成对出现且两个盒子里的糖果数相加必须为k的倍数)。
emmm。。首先想到的是暴力,双层for

for (int i=1; i<=n; i++)
		if (!v[i])
			for (int j=i+1; j<=n; j++) {
				if ((a[i]+a[j])%k==0 && !v[j]) {
					ans+=2;
					v[j]=1;
					break;
				}
			}

虽然有2s的时限,但双层for及时经过了优化也只跑了18组数据(当然没优化的话不到5组)
在这里插入图片描述
但仔细想一想就会明白,假如a为b的倍数,c不是b的倍数,那么a+c绝对不会是b的倍数。所以我们直接在输入的同时判断是否为k的倍数,然后sum++,再判断它的奇偶性。
对于不是k倍数的,我们可以先将它保存下来,然后挨个查找,结果发现,a[i]的数据在1到10亿,无法存储,我们就想到要压缩该数据。
接下来,想想如果(a+b)%k=0的话a%k+b%k也会等于0。又k<100,所以我们需要检索的范围也就缩小到了1到100;然后按照之上的暴力方法暴力一遍也就过了。。。
在这里插入图片描述

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int a[200050],v[200050];
int main() {
	int n,k,ans=0,num=0;
	scanf ("%d%d",&n,&k);
	for (int i=1; i<=n; i++) {
		scanf ("%d",&a[i]);
		if (a[i]%k==0) num++;    //是否为k的倍数
		else v[a[i]%k]++;        //压缩数据大小
	}
	ans=num/2;
	ans*=2;
	for (int i=1; i<k; i++)
		if (v[i])
			for (int j=i; j<k; j++) {
				if (i==j && (i+j)%k==0) {
					int ss=v[i]/2;
					ans+=ss*2;
					v[i]-=ss*2;
					if (v[i]) continue;
					else break;
				} 
				else if(v[j] && (i+j)%k==0){
					if (v[i]>v[j]) {
						ans+=2*v[j];
						v[i]-=v[j];
						v[j]=0;
						continue;
					} else {
						ans+=2*v[i];
						v[j]-=v[i];
						v[i]=0;
						break;
					}
				}
			}
	printf ("%d\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43906000/article/details/88358971
今日推荐