题目大意:
电梯有两个选项向上或向下,每层楼有一个参数ki,代表电梯可以再该楼层的基础上向上或向下移动ki层,限制条件是向上不能超过楼层总数n,向下不能少于一。输入总层数n和当前所在层数以及目标层数,然后是n个数分别代表第i层的移动范围。输出最少移动次数,若不可达,输出-1.
解题思路:
1.用Dijkstra算法,首先构建邻接矩阵,注意在构造时,要考虑i-k[i]<1和i+k[i]>n,i代表当前所在层。
1 #include<string.h> 2 #include<stdio.h> 3 #define INF 0x3f3f3f3f 4 int k[201]; 5 int g[1001][1001]; 6 int dis[1001],vis[1001]; 7 int t,s,d,x,y; 8 int a,b,n; 9 void dijkstra(int start) 10 { 11 int i,j,k; 12 memset(vis,0,sizeof(vis));//初始化vis数组,标记为都未访问过。 13 for(i=1; i<=n; i++) 14 { 15 if(i==start) 16 dis[i]=0; 17 else 18 dis[i]=INF; 19 }//除起始点外,其他点的dis都赋为正无穷 20 for(i=1; i<=n; i++) 21 { 22 int r; 23 int min=INF; 24 for(j=1; j<=n; j++) 25 if(!vis[j]&&dis[j]<min) 26 { 27 min=dis[j]; 28 r=j; 29 }找出当前未被访问的点中权值最小的点,对所有从该点出发的边进行松弛。 30 vis[r]=1; 31 for(k=1; k<=n; k++)//松弛操作 32 if(dis[k]<(dis[r]+g[r][k])) 33 dis[k]=dis[k]; 34 else 35 dis[k]=dis[r]+g[r][k]; 36 } 37 return; 38 } 39 int main() 40 { 41 int i; 42 while(scanf("%d",&n)!=EOF&&n) 43 { 44 memset(g,INF,sizeof(g)); 45 scanf("%d%d",&a,&b); 46 for(i=1; i<=n; i++) 47 { 48 scanf("%d",&k[i]); 49 } 50 for(i=1; i<=n; i++) 51 { 52 if(i-k[i]<1) 53 g[i][k[i]+i]=1; 54 if(i+k[i]>n) 55 g[i][i-k[i]]=1; 56 if(i-k[i]>=1&&i+k[i]<=n) 57 { 58 g[i][k[i]+i]=1; 59 g[i][i-k[i]]=1; 60 } 61 } 62 dijkstra(a); 63 if(dis[b]==INF) 64 printf("-1\n"); 65 else 66 printf("%d\n",dis[b]); 67 } 68 return 0; 69 }
2.BFS算法:
有向上走和向下走两种方法:
1 #include <iostream> 2 #include <stdio.h> 3 #include <queue> 4 using namespace std; 5 int n, start,end; 6 int a[205]; 7 bool vis[205], flag; 8 struct node 9 { 10 int x, step;//x记录当前所在层,step记录已经走了几次 11 } n1, n2, m; 12 int main() 13 { 14 int i; 15 while(scanf("%d", &n)!=EOF) 16 { 17 if(n== 0) 18 break; 19 scanf("%d %d", &start,&end); 20 for(i = 1; i <= n; i++) 21 { 22 scanf("%d", &a[i]); 23 vis[i] = false; 24 } 25 flag = false; 26 n1.x = start; 27 n1.step = 0; 28 queue<node> Q; 29 Q.push(n1);//起始点入队列 30 vis[n1.x] = true; 31 while(!Q.empty()) 32 { 33 m = Q.front(); 34 Q.pop(); 35 if(m.x == end) 36 { 37 flag = true; 38 break; 39 } 40 n1.x = m.x - a[m.x]; 41 n2.x = m.x + a[m.x]; 42 if(n1.x>0 && n1.x<=end && !vis[n1.x]) 43 { 44 n1.step = m.step + 1; 45 vis[n1.x] = true; 46 Q.push(n1); 47 } 48 if(n2.x>0 && n2.x<=end && !vis[n2.x]) 49 { 50 n2.step = m.step + 1; 51 vis[n2.x] = true; 52 Q.push(n2); 53 } 54 } 55 if(flag) 56 printf("%d\n", m.step); 57 else 58 printf("-1\n"); 59 } 60 return 0; 61 }