CF日常刷题篇:Omkar and Bad Story

以日记的形式进行更新每天在Codeforces中刷的题,大家可以随便看看,不会做过多的解释。

Omkar and Bad Story

大致题意是在原有数列的基础上添加(也可以不加)几个新的数,使得新数列是一个Nice数列。数列满足所有数互不相同。Nice数列的定义是,从中任意取出两个数 x x x y y y,满足 ∣ x − y ∣ |x-y| xy在数列中存在。

Input

4
3
3 0 9
2
3 4
5
-7 3 13 -2 8
4
4 8 12 6

Output

yes
4
6 0 3 9
yEs
5
5 3 1 2 4
NO
Yes
6
8 12 6 2 4 10

稍加分析既可发现,只要数列中出现负数,则该数列一定不满足Nice,并且一个Nice数列必须满足一条性质:将所有的数从小到大排序后,该数列一定为一个等差数列,且首项为0或公差。

问题就在于如何去找到公差,并且加数到数列里面。

这里选择用gcd来寻找公差,查询数列中最小的数与每个数的最大公约数,找到的最小的gcd便是公差。

int gcd(int a, int b) {
	return a % b == 0 ? b : gcd(b, a%b);
}

代码如下:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>

using namespace std;

int a[100000], b[100000];

int gcd(int a, int b) {
	return a % b == 0 ? b : gcd(b, a%b);
}

int main() {
	int T, n;
	
	scanf("%d", &T);
	while(T-- > 0) {
		bool fail = false, hasZero = false;
		int minA = 10000, maxA = 0, gcdMin;
		int num = 0;
		scanf("%d", &n);
		for(int i = 1; i <= n; i++) {
			scanf("%d", &a[i]);
			if(a[i] < 0) fail = true;
			if(a[i] == 0) {
				hasZero = true;
				continue;
			}
			minA = min(minA, a[i]);
			maxA = max(maxA, a[i]);
		}
		
		if(fail) {
			printf("NO\n");
			continue;
		}else printf("YES\n");
		
		gcdMin = minA;
		for(int i = 1; i <= n; i++) {
			if(!a[i]) continue;
			gcdMin = min(gcdMin, gcd(gcdMin, a[i]));
		}
		
		for(int i = 0; i <= maxA; i += gcdMin) {
			if(!i && !hasZero) continue;
			b[++num] = i;
		}
		
		printf("%d\n", num);
		for(int i = 1; i <= num; i++)
		printf("%d ", b[i]);
		printf("\n");
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值