第十届蓝桥杯c语言b组试题h详解【超详细】【新手向】

本文介绍了一种解决等差数列求最短项数的方法,通过冒泡排序找到数列中最大项和最小项的差值,计算公差并根据最大项的奇偶性确定项数。同时,博主分享了代码实现,强调了处理公差为0的特殊情况,并鼓励读者尝试简化代码。
摘要由CSDN通过智能技术生成

接下来我会详细的讲一下这道题,因为我本人也是新手,所以这道题不会是最优解,但一定非常的简单以及好理解(要是讲错了,大佬请在评论区指出QAQ),按照现在目前的测试来看,是没有问题的啦。

试题:H

时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分
【问题描述】
数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一
部分的数列,只记得其中 N 个整数。
现在给出这 N 个整数,小明想知道包含这 N 个整数的最短的等差数列有
几项?
【输入格式】
输入的第一行包含一个整数 N。
第二行包含 N 个整数 A 1 ,A 2 ,··· ,A N 。(注意 A 1 ∼ A N 并不一定是按等差数
列中的顺序给出)
【输出格式】
输出一个整数表示答案。
【样例输入】
5
2 6 4 10 20
【样例输出】
10
【样例说明】
包含 2、6、4、10、20 的最短的等差数列是 2、4、6、8、10、12、14、16、
18、20。

【评测用例规模与约定】
对于所有评测用例,2 ≤ N ≤ 100000,0 ≤ A i ≤ 1 0 9 10^9 109 。
————————————————

闲话

闲话
看到一个大佬给出的思路是:
1.排序后数列两两之间差值的GCD。
结果就是(a[max]-a[min])/GCD+1。
特判公差为0时答案为n。
但我认为有点复杂~~(小难)~~
————————————————

思路

思路
我将这道题分为了几个模块:
1.由于这道题并没有给你从小到大排序,我这里用的是冒泡排序
2.然后两两之间相减,用一个数组存储它们差值。
3.用打擂台的排序,将这个差值数组比出最小值,而那个最小值就是公差
4.公式:当等差数列的最大项是偶数时,最大项除最小差值=总项数
当等差数列的最大项是奇数时,(最大项除最小差值)+1=总项数
若公差为0,则项数就是输入的整数N
话不多说上代码!
————————————————

代码部分详解

int a[100000]={0};
	int n,i,j,t;
	scanf("%d\n",&n);
	for(i=0;i<n;i++)scanf("%d",&a[i]);
	
	for(i=0;i<n;i++)
	 for(j=0;j<n-i-1;j++)
	 	if(a[j]>a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}/*冒泡排序*/
	 	

这段代码就是思路1 的冒泡排序,没什么好讲的,要是冒泡不会的也可以用其他的排序方式,就算是冒泡也不是很难。

	int b[10000];
	for(i=0;i<n;i++){
		b[i]=a[i+1]-a[i]; 
	}/*与前一项相减,得到一个两项差值的数组*/
	

b数组就是思路2提到的存储差值的。
for循环里的代码功能就是两两相减。

int min=b[0];
	for(i=0;i<n-1;i++) 
	{
		if(b[i]<min)min=a[i];
	}/*算出最小的公差*/

思路3的打擂台,最小的那个就是公差。
至于为什么n-1,也是因为五个数只比了四次。
减1看起来不舒服的话,换成下面代码会舒服些:

int min=b[0];
	for(i=1;i<n;i++) 
	{
		if(b[i]<min)min=a[i];
	}

接下来的代码就是最后判断是否是公差是奇还是偶数或者是0了。

if(min!=0){
	if((a[n-1])%2==0)printf("%d",a[n-1]/min); /*因为"偶数"最大项除最小差值=总项数*/ 
	else printf("%d",(a[n-1]/min)+1);         /*"奇数"(最大项除最小差值)+1=总项数*/
}
else printf("%d",n);/*一定要注意公差是0的情况,项数为n*/ 
return 0; 

再次重温下公式:
当等差数列的最大项是偶数时,最大项除最小差值=总项数
当等差数列的最大项是奇数时,(最大项除最小差值)+1=总项数
若公差为0,则项数就是输入的整数N
————————————————

完整代码

#include<stdio.h>
int main()
{
	int a[100000]={0};
	int n,i,j,t;
	scanf("%d\n",&n);
	for(i=0;i<n;i++)scanf("%d",&a[i]);
	
	for(i=0;i<n;i++)
	 for(j=0;j<n-i-1;j++)
	 	if(a[j]>a[j+1]){t=a[j];a[j]=a[j+1];a[j+1]=t;}/*冒泡排序*/
    
	int b[10000];
	for(i=0;i<n;i++){
		b[i]=a[i+1]-a[i]; 
	}/*与前一项相减,得到一个两项差值的数组*/
	
	int min=b[0];
	for(i=1;i<n-1;i++) 
	{
		if(b[i]<min)min=a[i];
	}/*算出最小的公差*/
	if(min!=0){
	if((a[n-1])%2==0)printf("%d",a[n-1]/min); /*因为"偶数"最大项除最小差值=总项数*/ 
	else printf("%d",(a[n-1]/min)+1);         /*"奇数"(最大项除最小差值)+1=总项数*/
}
    else printf("%d",n);/*一定要注意公差是0的情况,项数为n*/ 
	return 0; 
	} 

总结

第一次法博客啰嗦了很多,感觉写蓝桥杯写成了c语言基础教学😂。
总之感觉这段代码改动并不大,主要是公式上的差异,能一段写完的,我为了方便理解改成了两段分为奇偶。
每个模块看起来比较工整,方便理解。
但我还是建议看完最后的各位,在大体理解解题思路之后,可以用更简便的方式去解题。

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值