题意说的是用梯子爬涂了油的竹竿,设定每次最多能登k步,那么在爬的过程中会产生两种情况:
- 如果1次正好登了k步,那么k就要减1
- 如果1次登了不到k步,那么k值不变
题目还举了个例子,k值为5,爬梯子的过程为1,6,7,11,13,也就是第一次爬到梯子的第1档,第二次爬到了第6档,第三次是第7档,第四次是第11档,第五次是第13档,那么爬梯子过程中k值的变化如下:
第一次,登了1步,爬到第1档,1<k,因此k值不变,k=5
第二次,登了5步,爬到第6档,5==k,因此k--,k=4
第三次,登了1步,爬到第7档,1<k,因此k值不变,k=4
第四次,登了4步,爬到第11档,4==k,因此k--,k=3
第五次,登了2步,爬到第13档,2<k,因此k值不变,k=3
问,根据输入的爬梯子步骤,求最小的k值。
其实也算是简单题,直接根据输入的数据模拟,记录每次爬梯子的跨度为dif,并设要求的最小值为minv,变化的k值由k来表示。那么模拟过程可以表示如下:
minv = k = 0;
while(爬梯次数n > 0){
if(k > dif)
{
continue;//k值不变,继续
}
else if(k == dif)
{
k--;//根据规则,k要减1
}
else if (k < dif)
{
//这里就要根据minv分情况了
if(minv >= dif)//k<dif但是minv>=dif,说明原来的minv值还是太小,使得k值在经过若干次循环、自减之后,也已经变得太小,无法满足本次爬梯子的跨度dif了
{
minv++;//那么只能minv再加1
k = minv;//同时再将k值初始化为minv,以便继续模拟
}
else if(minv < dif) //说明这个minv值太小,比梯子跨度dif还小,肯定不行
{
minv = dif //设定minv值为梯子的高度差
k = minv - 1//根据规则,k要减1
}
}
n--;
}
print(minv);//模拟结束,此时minv中的k值就是要求的最小k值。
python版本AC代码
testcase = int(input())
for i in range(testcase+1):
if i == 0:
continue
n = int(input())
ladder = [0]
ladder.extend(list(map(int,input().split())))
k = 0
minv = 0
for j in range(len(ladder)-1):
if k < ladder[j+1]-ladder[j]:
if minv >= ladder[j+1]-ladder[j]:
minv += 1
k = minv
else:
minv = ladder[j+1]-ladder[j]
k = minv - 1
elif k == ladder[j+1]-ladder[j]:
k -= 1
print("Case %d: %d"%(i,minv))
C++版本AC代码
#include <iostream>
#include<cstdio>
using namespace std;
//#define ZANGFONG
int main()
{
#ifdef ZANGFONG
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif // ZANGFONG
int testcase,i,j,n,minv,k;
int first,second;
scanf("%d\n",&testcase);
for(i = 1; i <= testcase; i++)
{
scanf("%d\n",&n);
first = second = minv = k = 0;
for(j = 0; j < n; j++)
{
scanf("%d",&second);
if(k < second - first)
{
if(minv >= second - first)
{
minv++;
k = minv;
}
else
{
minv = second - first;
k = minv - 1;
}
}
else if(k == second - first) k--;
first = second;
}
printf("Case %d: %d\n",i,minv);
}
return 0;
}