HDU 1548 A strange lift (暴力搜索)

题面

Problem Description
There is a strange lift.The lift can stop can at every floor as you want, and there is a number Ki(0 <= Ki <= N) on every floor.The lift have just two buttons: up and down.When you at floor i,if you press the button "UP" , you will go up Ki floor,i.e,you will go to the i+Ki th floor,as the same, if you press the button "DOWN" , you will go down Ki floor,i.e,you will go to the i-Ki th floor. Of course, the lift can't go up high than N,and can't go down lower than 1. For example, there is a buliding with 5 floors, and k1 = 3, k2 = 3,k3 = 1,k4 = 2, k5 = 5.Begining from the 1 st floor,you can press the button "UP", and you'll go up to the 4 th floor,and if you press the button "DOWN", the lift can't do it, because it can't go down to the -2 th floor,as you know ,the -2 th floor isn't exist.
Here comes the problem: when you are on floor A,and you want to go to floor B,how many times at least he has to press the button "UP" or "DOWN"?

Input
The input consists of several test cases.,Each test case contains two lines.
The first line contains three integers N ,A,B( 1 <= N,A,B <= 200) which describe above,The second line consist N integers k1,k2,....kn.
A single 0 indicate the end of the input.

Output
For each case of the input output a interger, the least times you have to press the button when you on floor A,and you want to go to floor B.If you can't reach floor B,printf "-1".

Sample Input
5 1 5
3 3 1 2 5
0

Sample Output
3

思路

我又来搜索了,每天搜索,haha。不过好像这原本是一道最短路的题目,也是搜了题解才知道的。我可能最近搜多了,看了题面上来就想搜了。这题dfs和bfs都很好想,我是一上来就深搜了,我们两种做法都讲一下吧。dfs的话要注意的点就是要开一个数组记录每一层的最短距离,因为你花更长的时间缺回到同一层显然是不值得的,所以我们记录一个数组用于剪枝,然后直接递归访问上升或者下降的状态。bfs的话就差不多是模板了,直接开队列访问就好了。

代码实现

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int maxn=205;
const int inf=0x3f3f3f3f;
int option[205];
int ans[maxn];
int n,m,s;
int finalans;
void dfs (int floor,int step) {
    if (floor<1||floor>s) return;   //非法情况
    if (floor==m&&step<finalans) {
        finalans=step;              //更新最短步数
        return ;
    } 
    if (step>=ans[floor]) return ;    //剪枝,如果再次返回这层楼显然是不对的
    ans[floor]=step;
    dfs (floor+option[floor],step+1);   //dfs分上下走
    dfs (floor-option[floor],step+1);
    return;
}
int main () {
   while (cin>>s) {
      if (s==0) break;
      cin>>n>>m;
      for (int i=1;i<=s;i++) {
          cin>>option[i];
          ans[i]=inf;
      }
      finalans=inf;
      dfs (n,0);
      if (finalans==inf) cout<<"-1"<<endl;
      else cout<<finalans<<endl;
   }
    return 0;
}
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<iostream>
using namespace std;
struct node {
    int pos,step;
}st;
const int maxn=205;
int option[maxn];
int s,n,m;
int vis[maxn];
bool check (int x) {
   if (vis[x]||x<1||x>s) return false;
   return true;
}
int bfs (int n) {   
   queue<node> q;
   st.pos=n;
   st.step=0;
   q.push(st);
   node now,next;
   memset (vis,0,sizeof (vis));
   vis[st.pos]=1;
   while (!q.empty()) {
       now=q.front();
       q.pop();
       if (now.pos==m) return now.step;
       for (int i=0;i<2;i++) {
           if (i==0) next.pos=now.pos+option[now.pos];
           else next.pos=now.pos-option[now.pos];
           next.step=now.step+1;
           if (check(next.pos)) {
               q.push(next);
               vis[next.pos]=1;
           }
       }
   }
   return -1;
}
int main  () {
    while (cin>>s) {
        if (s==0) break;
        cin>>n>>m;
        for (int i=1;i<=s;i++) cin>>option[i];
        int ans=bfs (n);
        cout<<ans<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hhlya/p/13159118.html