题目大意
有一个奇怪的电梯,他的每一层都只能去往固定的一层,不能随意去往任意一层。
每一层都对应一个数字,假设第i层对应k,那么含义为:在第i层的电梯下一次移动只能移向i+k层或i-k层。问至少移动多少次,可以从第A层移动到第B层。
两种思路:
一是广搜,从A层开始向外扩展,查找到达“临近”的层数的最少步数,直到找到B层,即为答案。需要将给定的k转化成第i层可以去往的i+k或i-k,注意记得判断越界和访问标记就可以了。
二是最短路算法,这里用的是Dijkstra算法,也是裸裸的,很容易敲。但是!!!我WA了好多发,最后和网上很多代码对比之后发现少了一句话,加上这句话就A了。
dis[a]=0;
dis数组是从A层到任意一层的最少步数。dis[a]即从A到A层的步数为0。我在写代码的时候忘记判断这个特殊情况,估计是被卡了。所以以后要注意特判啊!!!
BFS AC代码
#include<stdio.h>
#include<string.h>
#include<queue>
#include<algorithm>
#include<math.h>
#define maxn 205
using namespace std;
struct node{
int f;
int step;
node(int f=0,int step=0):f(f),step(step){}
};
int main()
{
int n,a,b;
int next[maxn];
bool book[maxn];
queue<node> q;
while(~scanf("%d",&n))
{
if(n==0)
break;
scanf("%d%d",&a,&b);
while(!q.empty())
q.pop();
bool success=false;
memset(book,false,sizeof(book));
for(int i=1;i<=n;i++)
scanf("%d",&next[i]);
q.push(node(a,0));
book[a]=true;
while(!q.empty()){
node temp=q.front();
q.pop();
if(temp.f==b){
printf("%d\n",temp.step);
success=true;
break;
}
if(temp.f+next[temp.f]<=n&&book[temp.f+next[temp.f]]==false){
book[temp.f+next[temp.f]]=true;
q.push(node(temp.f+next[temp.f],temp.step+1));
}
if(temp.f-next[temp.f]>=1&&book[temp.f-next[temp.f]]==false){
book[temp.f-next[temp.f]]=true;
q.push(node(temp.f-next[temp.f],temp.step+1));
}
}
if(!success)printf("-1\n");
}
return 0;
}
Dijkstra AC代码
#include<stdio.h>
#include<algorithm>
#include<math.h>
using namespace std;
#define maxn 205
#define inf 999999
int maze[maxn][maxn];
int dis[maxn];
void init()
{
for(int i=0;i<maxn;i++){
for(int j=0;j<maxn;j++)
maze[i][j]=inf;
dis[i]=inf;
}
}
int main()
{
int n,a,b;
int u;
bool book[maxn];
while(1)
{ scanf("%d",&n);
if(n==0)
break;
scanf("%d%d",&a,&b);
init();
for(int i=1;i<=n;i++){
int temp;
scanf("%d",&temp);
if(i+temp<=n)
maze[i][i+temp]=1;
if(i-temp>=1)
maze[i][i-temp]=1;
}
for(int i=1;i<=n;i++){
dis[i]=maze[a][i];
book[i]=false;
}
dis[a]=0;///*****************************
book[a]=true;
int minx;
for(int i=1;i<n;i++){
///找到距离a最近的点
minx=inf;
for(int j=1;j<=n;j++){
if(!book[j]&&dis[j]<minx){
minx=dis[j];
u=j;
}
}
if(minx==inf)
break;
book[u]=true;
///根据这个找到的最近的点进行松弛
for(int j=1;j<=n;j++){
//if(maze[u][j]<inf)
if(dis[j]>dis[u]+maze[u][j]&&!book[j])
dis[j]=dis[u]+maze[u][j];
}
}
if(dis[b]==inf) printf("-1\n");
else printf("%d\n",dis[b]);
}
return 0;
}