题意:在电梯的第i层只能上ki层或下ki层,但是不能到达低于一层或高于n层,
给定起点与终点,要求出最少要按几次键
分析:这题可以用BFS从上下两个方向搜索,也可以用最短路径
若用最短路,则应将邻接矩阵中能到达的边的权值赋为1,这样就转化为了基本的最短路
BFS代码:
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int s[210],vis[210],dis[210],n,a,b;
void bfs()
{
queue<int> q;
int i;
memset(vis,0,sizeof(vis));
memset(dis,0,sizeof(vis));
q.push(a);
vis[a]=1;
while(!q.empty()){
i=q.front();
q.pop();
if(i==b) //到达终点时结束
break;
if(i+s[i]<=n&&!vis[i+s[i]]){ //往上搜索
q.push(i+s[i]);
vis[i+s[i]]=1;
dis[i+s[i]]=dis[i]+1;
}
if(i-s[i]>=1&&!vis[i-s[i]]){ //往下搜索
q.push(i-s[i]);
vis[i-s[i]]=1;
dis[i-s[i]]=dis[i]+1;
}
}
}
int main()
{
int i;
while(scanf("%d",&n)!=EOF){
if(n==0)
break;
scanf("%d%d",&a,&b);
for(i=1;i<=n;i++)
scanf("%d",&s[i]);
if(a==b){ //起点和终点相等是需要按 0 次
printf("0\n");
continue;
}
bfs();
if(!dis[b]) //当dis[b]=0时,说明无法到达,输出-1
dis[b]=-1;
printf("%d\n",dis[b]);
}
return 0;
}
dijkstra算法
#include<stdio.h>
#include<limits.h>
#include<string.h>
int a[210][210],dis[210],vis[210];
void dijkstra(int n,int pos)
{
int i,j,min;
memset(vis,0,sizeof(vis));
vis[pos]=1;
for(i=1;i<=n;i++)
dis[i]=a[pos][i];
dis[pos]=0;
for(i=1;i<n;i++){
min=INT_MAX;
for(j=1;j<=n;j++)
if(!vis[j]&&dis[j]<min){
min=dis[j];
pos=j;
}
vis[pos]=1;
for(j=1;j<=n;j++)
if(!vis[j]&&a[pos][j]!=INT_MAX&&dis[pos]+a[pos][j]<dis[j])
dis[j]=dis[pos]+a[pos][j];
}
}
int main()
{
int n,i,j,l,r,c;
while(scanf("%d",&n)!=EOF){
if(n==0)
break;
for(i=1;i<=n;i++){
for(j=1;j<=n;j++)
a[i][j]=INT_MAX; //初始化为无限大
}
scanf("%d%d",&l,&r);
for(i=1;i<=n;i++){
scanf("%d",&c);
if(i+c<=n)
a[i][i+c]=1; //将能直接到达的边权值存为1
if(i-c>=1)
a[i][i-c]=1;
}
dijkstra(n,l);
if(dis[r]==INT_MAX)
dis[r]=-1;
printf("%d\n",dis[r]);
}
return 0;
}