接下来我会详细的讲一下这道题,因为我本人也是新手,所以这道题不会是最优解,但一定非常的简单以及好理解(要是讲错了,大佬请在评论区指出QAQ),按照现在目前的测试来看,是没有问题的啦。
时间限制: 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
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语言基础教学。
总之感觉这段代码改动并不大,主要是公式上的差异,能一段写完的,我为了方便理解改成了两段分为奇偶。
每个模块看起来比较工整,方便理解。
但我还是建议看完最后的各位,在大体理解解题思路之后,可以用更简便的方式去解题。