2020NYIST个人积分赛第八场-A

题面

原题链接:计蒜客T1271

思路

我真的问了大佬好久也查了好久。。我 tcl QWQ
这个题很难直接枚举,不过可以考虑能构成完美子数组的几种情况:
1:数组里所有元素都能被K整除且数组长度至少为2
2:k为偶数时,数组里所有元素都对K取模的结果都是K/2,且数组长度至少为2;这样数组里任意两个数的和都是k的倍数
3:可用map 或 set记录某个余数是否出现过

代码

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <vector>
using namespace std;
map<int, bool> r; //用于记录这个数的余数是否出现过
int main()
{
	int n, k, a;
	cin >> n >> k;
	if (n < 2) //如果不够两个数字 直接输出-1并结束
	{
		cout << "-1" << endl;
		return 0;
	}
	//分情况统计
	int b=0, c=0, sum = 0;
	for (int i = 1; i <= n; i++)
	{
		cin >> a;
		if (a % k == 0)
			b++; //统计能被k整除的数有多少
		if (a % k == k / 2)
			c++;		   //统计能被k/2整除但不能被k整除的数有多少
		if (r[a % k] == 0) //如果不能被k整除也不能被k/2整除  就看看余数是否标记过
		{
			r[k - a % k] = 1; //把需要补齐的余数标记  eg a=7,k=5.  a%k==2  那就把5-2=3 即k-a%k标记
		}
		else
		{
			sum = 2; //如果标记过了 那就代表已经有一个可以与它组成一对的数了。就至少有2个了
		}
	}
	int ans;
	if (k % 2 == 0) //如果k是偶数 那么不能被k整除 能被k/2整除的任意两个数组合 相加的和是k的倍数
	{
		if (sum == 0 && b < 2 && c < 2) //三种情况都不符合
			cout << "-1" << endl;
		else
		{
			ans = max(sum, max(b, c));//求三种情况的最大值(最长子序列)
			cout << ans << endl;
		}
	}
	else //k不是偶数的时候不存在被k/2整除的情况
	{
		if(sum==0&&b<2)
			cout << "-1" << endl;
		else
		{
		ans = max(b, sum);//求两种情况的最大值
		cout << ans << endl;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值