题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1548
题目大意:就是说有一个很奇怪的升降机,它有两个按钮UP和DOWN,给你一些数i表示层数,并且每层对应的Ki,如果按UP按钮,会从第i层升到第i+Ki层;如果按了DOWN则会从第i层降到第i-Ki层;并规定能到的层数为1到N,根据常识也知道。现在的要求就是给你N,A,B和一串数K1到Kn,问你从A到B,至少按几下按钮。
解法有多种:
解法一:最短路求解:
代码:
#include<iostream> using namespace std; #define INF 100000000 int map[205][205]; int dist[205],S[205]; int N,A,B; int Dijkstra(int u,int v) { memset(S,0,sizeof(S)); int i,j,k; for(i=1;i<=N;i++) { dist[i]=map[u][i]; } S[u]=1; dist[u]=0; for(i=1;i<N;i++) { int min=INF,t; for(j=1;j<=N;j++) { if(!S[j]&&dist[j]<min) { t=j; min=dist[j]; } } if(min==INF)//说明不存在从A到B的任何路径 return -1; if(t==v)//已到达B return min; S[t]=1; for(k=1;k<=N;k++) { if(!S[k]&&dist[t]+map[t][k]<dist[k]) dist[k]=dist[t]+map[t][k]; } } return -1; } int main() { int i,j,c; while(cin>>N,N) { cin>>A>>B; for(i=1;i<=N;i++) { for(j=1;j<=N;j++) map[i][j]=i==j?0:INF; } for(i=1;i<=N;i++) { cin>>c; if(i+c<=N) map[i][i+c]=1; if(i-c>=1) map[i][i-c]=1; } if(A==B)//如果坑爹的题目问你从i到i就坑死了 { cout<<"0"<<endl; } else cout<<Dijkstra(A,B)<<endl; } return 0; }
第二种解法:广搜
代码:
#include<iostream> using namespace std; #include<queue> int n; struct node{ int c; int num; }m,n1,n2,t; queue<node> Q; int main() { int a,b,c[205],s; bool map[205],flag; int i; while(~scanf("%d",&n),n) { scanf("%d%d",&a,&b); for(i=1;i<=n;i++) { scanf("%d",&c[i]); map[i]=false; } if(a==b) { printf("0\n"); continue; } m.c=a; m.num=0; Q.push(m); map[m.c]=true; flag=false; while(!Q.empty()) { t=Q.front(); Q.pop(); if(t.c==b) { flag=true; s=t.num; break; } n1.c=t.c+c[t.c]; if(n1.c>=1&&n1.c<=n&&!map[n1.c]) { n1.num=t.num+1; Q.push(n1); map[n1.c]=true; } n2.c=t.c-c[t.c]; if(n2.c>=1&&n2.c<=n&&!map[n2.c]) { n2.num=t.num+1; Q.push(n2); map[n2.c]=true; } } if(flag==true) printf("%d\n",s); else printf("-1\n"); while(!Q.empty()) Q.pop(); } return 0; }
注意如果没有给你走的的层数标记的话,在一种极端的情况下会在i和j层不断地走从而导致的就是超内存,被它卡了5次超内存;没能彻底理解它,真差