蓝桥杯 等差数列【第十届】【省赛】【C组】C++ 暴力枚举

资源限制

时间限制:1.0s   内存限制:256.0MB

思路简介

既然是求最短等差数列,显然一定是以最小的为数列首元素,最大的为末尾元素。先利用sort函数升序排列元素。然后采用暴力枚举公差的方法,(暂时不了解暴力枚举 算法的可以戳此链接,也可以看一下我之前的一些博客,包括典题和详解以及AC代码)   

洛谷P1217 [USACO1.5]回文质数 Prime Palindromes 暴力枚举 C++_Prudento的博客-CSDN博客洛谷P1149 [NOIP2008 提高组] 火柴棒等式 暴力枚举 C++(打表)_Prudento的博客-CSDN博客_c++火柴棒完美立方 暴力枚举 C++_Prudento的博客-CSDN博客_c++ 暴力枚举生理周期 暴力枚举 C++_Prudento的博客-CSDN博客

称硬币 暴力枚举 C++_Prudento的博客-CSDN博客

洛谷P1618 三连击(升级版)C语言 暴力枚举 详解_Prudento的博客-CSDN博客_c语言暴力枚举

洛谷 P2089 烤鸡 C语言 (暴力枚举)_Prudento的博客-CSDN博客

前面说到要暴力枚举公差d,即 d从0枚举到最大值和最小值之差(其实没必要枚举这么多,只要枚举到一半就行,但是其实枚举到最大只差也不会TLE,所以避免一些特殊情况,那就干脆枚举的最大值设为此。为什么最大值设成这个而不是其他?因为显然,当公差为最大值和最小值之差时,那么最小的元素和最大的元素应该是相邻的,那么此时只有n=2此公差才可能合法。n>2时此公差枚举到这显然肯定不合法了,更大的肯定更不合法。所以便确定的枚举变量d的范围。但是要注意,对于公差为0,即常数列可以O(n)的速度特判一下,如果是那么直接输出并结束程序。因为如果是常数列显然最短长度就是原数列的长度。那么下一步则确定如何对枚举变量进行操作,便是遍历每一位元素,只要(最大的元素-每一位元素)%d=0,说明此公差是合法的,每个数的间距都是公差的倍数。

确定公差合法后,那么项数便是(此处为升序排列)(最大值-最小值)/d+1 

最后对每一次合法的公差取使得数列长度最短的即可。

Code

#include<bits/stdc++.h>
using namespace std;
int n,len=0x3f3f3f3f,i,d,tlen,flag,t;
int a[100010];
int now[100010];
inline int read() {//利用getchar比scanf快从而实现快读
	char ch = getchar(); int x = 0;
	while (ch >= '0' && ch <= '9') {
		x = x * 10 + ch - '0';
		ch = getchar();
	}return x;
}
int main(){
	n = read();
	for (i = 1; i <= n; i++)
		now[i] = read();
	sort(now + 1, now + 1 + n);
	t = now[1];
	for (i = 2; i <= n; i++) {
		flag = t - now[i];
		if (flag)break;//如果flag!=0,说明不可能是常数列
	}//查看是否所有的数相同
	if (!flag) {
		printf("%d", n);
		exit(0);
	}//flag始终是0说明是常数列,直接输出最短长度便是现在的长度,并终止程序
	//非常数列,枚举公差从1到最大的值和最小的值的差
	for (d = 1; d <=now[n]-now[1]; d++) {//从1开始枚举公差
		for (i=1; i <= n; i++) 
			if ((now[n]-now[i])%d)break;//如果两数之差取余公差不为0,那么此公差非法
		if (i == n+1) {//说明此公差合法
			tlen = (now[n] - now[1]) / d + 1;//项数
			len = min(tlen, len);
		}
	}
	printf("%d", len);
	
	return 0;
}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Prudento

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值