题解
2024-06-05 19:07:58
发布于:江苏
15阅读
0回复
0点赞
已修改格式
是大家都能想到的广搜
#include <bits/sdtc++.h>
#define int long long
using namespace std;
int n,a,b,k[210],vis[210];
struct st{
int x,cnt;//x是当前层数,cnt是花费的次数
};
queue <st> q;
int bfs(int x){
q.push(x,0);//注意初始状态是0
vis[x]=1;
while(q.size()){
st node=q.front();
q.pop();
if(node.x==b)return node.cnt;
for(int i=-1;i<=1;i++){//方便运算
int nx=node.x+k[node.x]*i;
if(vis[nx]||nx<1||nx>n)continue;
q.push({nx,node.cnt+1});
vis[nx]=1;
}
return -1;
}
int main(){
cin>>n>>a>>b;
for(int i=1;i<=n;i++)cin>>k[i];
cout>>bfs(a);
return 0;
}
就是深搜
但是如果写的像下面一样很单纯
下面代码能得
#include <iostream>
#define int long long
using namespace std;
int n,a,b,k[210],vis[210],mx=1e8;
void dfs(int x,int step){//这边需要step放在这来,回溯的时候好操作
if(x==b){
mx=min(step,mx);//取正确答案
return ;
}
if(step>mx)return ;//剪枝(不剪就55)
for(int i=-1;i<=1;i++){
int nx=x+i*k[x];
if(nx>n||nx<1||vis[nx])continue
vis[nx]=1;
dfs(nx,step+1);
vis[nx]=0;
}
}
int main(){
cin>>n>>a>>b;
for(int i=1,i<=n;i++)cin>>k[i];
vis[a]=1;
dfs(a,0);
if(mx==1e8)cout<<"-1";//判断是否可以
else cout<<mx;
return 0;
所以记忆化启动!!!
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,a,b,k[210],vis[210],mx=1e8,dis[210];
void dfs(int x,int step){
if(x==b){
mx=min(step,mx);
return ;
}
if(dis[x]&&dis[x]<step)return ;//记忆化,从任意点到这个点的最少步数,如果比step小,就返回搜最优解
if(step>mx)return ;
for(int i=-1;i<=1;i++){
int nx=x+i*k[x];
if(nx>n||nx<1||vis[nx])continue;
vis[nx]=1;
dfs(nx,step+1);
dis[nx]=step;//任意点到这个点的步数
vis[nx]=0;
}
}
signed main(){
cin>>n>>a>>b;
for(int i=1;i<=n;i++)cin>>k[i];
vis[a]=1;
dfs(a,0);
if(mx==1e8)cout<<"-1";
else cout<<mx;
return 0;
}
以上代码都有防抄袭,不是代码错误
为了防止误会,所以只有编译错误
全部评论 1
顶一下
2024-05-07 来自 江苏
0
有帮助,赞一个