算法设计题4.3 等差数列
问题描述
如果可以给定一个整数序列,可以把它分割为若干个等差数列。比如给定一个序列(8,6,4,2,1,4,7,10,2)可以被分割为( 8,6,4, 2)、( 1,4,7)和( 2)三个等差数列。不幸的是有些整数序列中包含缺失值,用-1 代替,缺失值的可以取大于0 的任意整数值。这种情况下随着缺失值的取值的变化,序列的分割情况也会发生变化。
编程任务
给定一个整数序列 a = (a1,a2,...,an), ai 由正整数和-1 组成,-1 表示缺失值。求这个序列最少可以组成多少个等差数列
数据输出
输出只有一行,最少的等差序列数。
python版:
n = int(input()) a = list(map(int, input().split())) i = 0 ans = 0 while i < n: ans += 1 i1 = i while i1 < n and a[i1] == -1: i1 += 1 if i1 == n: break i2 = i1 + 1 while i2 < n and a[i2] == -1: i2 += 1 if i2 == n: break dist = i2 - i1 step = (a[i2] - a[i1]) // dist if (a[i2] - a[i1]) % dist != 0 or (step > 0 and a[i1] - (i1 - i) * step <= 0): i = i2 continue i3 = i2 + 1 while i3 < n: nxt = a[i2] + step * (i3 - i2) if nxt <= 0 or (a[i3] != -1 and a[i3] != nxt): break i3 += 1 i = i3 print(ans)
C ++ 版:
#include<iostream> #include<cstdio> using namespace std; __int64 a[200010],d; int n; int cnt=0; int k=1; int i,j; int main(){ cin>>n; for(i=1;i<=n;i++) scanf("%I64d",&a[i]); while(k<=n){ cnt++; i=k; while(a[i]==-1)i++;//找到第一个不为-1的数作为等差序列的开始 j=i+1; while(a[j]==-1)j++;//找到第二个不为-1的数作为等差序列的结束 if(j>n) break; d=(a[j]-a[i])/(j-i); if((a[j]-a[i])%(j-i)||a[j]-d*(j-k)<=0){ k=j; continue; } k=j+1; while(k<=n&&a[j]+d*(k-j)>0&&(a[k]==-1||a[k]==a[j]+d*(k-j))){ k++; } } cout<<cnt<<endl; return 0; }