(提早声明,本篇博客可能质量不如前几篇好,毕竟连肝四篇博客我已经快吐血了✿◕‿◕✿)ios
看到这道题,第一时间想到的就是:深搜!!数组
因而我打了一个只能获得20分,剩下都MLE的深搜代码:函数
#include<iostream> #include<cstdio> using namespace std; int n,m[210],a,b,xq=0,minn=9999; void dfs(int idx,int cishu){ if(idx==b){ xq=1;//若是到达了我么就用小旗标记一下,以便于最后输出 minn=min(minn,cishu);//每次到达想要的那个楼层时,都要取最小值,这样咱们就能够获得只要要按几回按钮了。 return; } //由于在每一层能作的操做只有两个,因此咱们作两个判断就够了,若是不越界的话,进行深搜就好啦(●'◡'●) if(idx-m[idx]>0){ dfs(idx-m[idx],cishu+1); } if(idx+m[idx]<=n){ dfs(idx+m[idx],cishu+1); } } int main(){ scanf("%d%d%d",&n,&a,&b); for(int i=1;i<=n;i++){ scanf("%d",&m[i]); }//以上全是输入 dfs(a,0);//调用深搜函数 if(xq!=0) printf("%d\n",minn);//输出,若是小旗不等于零就说明咱们到达过第b层楼 else printf("-1\n");//不然,也就是没有到达过第b层楼,就按照题目要求输出-1 return 0;//不要忘记return 0喔 }
MLE是什么来着?让咱们百度一下:优化
看到这里你还不知道该干什么吗!俗话说,优化是个好东西spa
咱们来用一个数组,把咱们判断过的标记上,而后下次再判断到这个点咱们就先看这个点有没有被标记,若是被标记了那也就不用继续下去了,反正已经判断过了。code
//数组定义个1000就好啦,反正数据也不大 hh[idx]=1;//每次hh[idx]都等于1,而后后面进行深搜的时候它就不会被搜到喽,能够节省很多时间呢 if(idx-m[idx]>0&&hh[idx-m[idx]]==0){//判断idx-m[idx]是否被算过 dfs(idx-m[idx],cishu+1);//若是没有被计算过,那么idx-m[idx],次数+1啦 } if(idx+m[idx]>0&&hh[idx+m[idx]]==0){//判断idx+m[idx]是否被算过 dfs(idx+m[idx],cishu+1);//跟上面同样,若是没有被计算过,那么idx+m[idx],次数+1啦 } hh[idx]=0;//最后不要忘了归零!很重要的! //若是你不归零会影响到后面计算,可能明明这一条路是最小的次数,结果就由于你忘了归零,成功错过正确答案
可是这样只有80分......咱们还能怎么优化呢?blog
若是当前的次数已经大于minn了呢......那么继续算下去不久没有意义了?ci
那咱们就再加一个判断条件:博客
hh[idx]=1; if(idx-m[idx]>0&&cishu<minn&&hh[idx-m[idx]]==0){ //加上这个特判就万事大吉了!若是当前次数已经大于等于minn那继续算下去就没有意义了,反正算到最后minn仍是不变,因此咱们只在当前次数小于minn的时候才算下去 dfs(idx-m[idx],cishu+1); } if(idx+m[idx]>0&&cishu<minn&&hh[idx+m[idx]]==0){ //这个跟上面那个道理是同样的啦 dfs(idx+m[idx],cishu+1); } hh[idx]=0;
最后献上完整代码:io
#include<iostream> #include<cstdio> using namespace std; int n,m[210],a,b,xq=0,minn=9999,hh[1010];//minn不能等于很小,否则跟其余的比小他最小怎么办 void dfs(int idx,int cishu){//深搜函数 if(idx==b){//出口,若是当前楼层就是第b层,那么就让小旗标记一下,取按键次数的最小值,而后返回 xq=1; minn=min(minn,cishu); return; } hh[idx]=1;//标记idx if(idx-m[idx]>0&&cishu<minn&&hh[idx-m[idx]]==0){ //次数若是大于等于minn那么计算下去就没意义了,反正算到最后minn不会有变化 //若是hh数组的第idx-m[idx]项没有被标记,也就是说他没有被判断过,咱们就能够继续了 dfs(idx-m[idx],cishu+1);//进行深搜,次数每次加一不要忘 } if(idx+m[idx]>0&&cishu<minn&&hh[idx+m[idx]]==0){//这个判断跟上一个是同样的,不过一个加一个减 dfs(idx+m[idx],cishu+1);//进行深搜,注意这里是+而不是- } hh[idx]=0;//取消标记 return;//返回上一层 } int main(){ scanf("%d%d%d",&n,&a,&b); for(int i=1;i<=n;i++){ scanf("%d",&m[i]); }//以上为输入 dfs(a,0);//调用函数 if(xq!=0) printf("%d\n",minn);//输出,小旗若是不等于0也就表示咱们到达过第b层,输出minn就行了 else printf("-1\n");//不然小旗等于0,也就是说咱们从未到达过第b层,按照题目要求输出-1 return 0; }