等差数列
(https://www.luogu.com.cn/problem/P8682)
第一眼下去,好简单,结果交上去一个t,三个wa,还是不能小看蓝桥杯的模拟的
废话不多说,开始解读题目
首先题目很容易理解,给定一组缺失的数列,叫我们找等差数列最少的项数
再看看例子,再细读一遍题目,发现它已经给定第一项和最后一项了
上公式:an = a1 + (n-1)*d,问题转移到找等差上
易错点
1.它给的例子很坑,如果你的差是2,是刚好能从第一项到最后一项的,但是 如果是 3 6 8 的话你发现最小的差是2,但你不能从第一项到最后一项
我第一次写的时候就是从最后一项往前跑,如果最后一项减去第一项的差刚好能使 第一项加差后等于第二项那么就能确定差了进而能确定最少的项了,就被t了,还wa了三,wa了的其中之一的数据就包括像 3 6 8 这样的例子
while (step){
ll de = TY[step] - TY[0];
if(TY[0] + de == TY[1]){
des = de;
break;
}
else step--;
}
ll ans = 0;
for (ll i = TY[0]; i <= TY[n-1]; i+=des) {
ans ++;
}
2.注意差为0的情况
3.不能直接以排序后的第二项减去第一项的值作为差(当然如果你是一个个跑上去的,那就不用注意这点,但是好像会被t)有可能你用an = a1 + (n-1)*d 去判断的时候你发现第一项可以满足,但是后边的几项可能就不满足了
那再换一个思路,用从小到大排列后的第二项减去第一项的值作为差值(还有一个小坑点,要注意int的向下取整可能存在多种情况成立,但好像数据不够强,没有这个判定)
sort(ve.begin(),ve.end(),cmp);
int mi = ve[0],ma = ve[n-1];
int be = ve[1] - ve[0];
if(be == 0){
cout << n;
return 0;
}else {
int ans = be;
/*
*a2 = a1 + be
* a3 = a2 + be = a1 + 2* be
* an = a1 + (n-1) * be
*/
int ans1 = INT32_MAX;
for (int i = be; i >= 1; i--) {
double nn =(1.0*(ma - mi))/i;
if(nn == (int) nn) {
int nnn = (int) nn;
if (mi + nn * i == ma) {
ans1 = min(ans1, nnn + 1);
}
}
}
cout << ans1;
}
结果是还是wa了两 -->第一项可以满足,但是后边的几项可能就不满足了
A代码:
int mi = ve[0],ma = ve[n-1];
int be = INT32_MAX;
for (int i = 0; i < n-1; i++) {
be = min(be,ve[i+1] - ve[i]);
}
if(be == 0){
cout << n;
return 0;
}else {
int ans = be;
/*
*a2 = a1 + be
* a3 = a2 + be = a1 + 2* be
* an = a1 + (n-1) * be
*/
int ans1 = INT32_MAX;
for (int i = be; i >= 1; i--) {
double nn =(1.0*(ma - mi))/i;
if(nn == (int) nn) {
int nnn = (int) nn;
if (mi + nn * i == ma) {
ans1 = min(ans1, nnn + 1);
}
}
}
cout << ans1;
}
标签:ma,ve,nn,int,mi,第一项,match,mistake
From: https://www.cnblogs.com/TFOREVERY/p/17047302.html