bfs 2016.3.6

1、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

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

int K[210];
int vis[210];

struct node {
    int floor;
    int count;
};

int bfs(int low, int high, int N);

int main()
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    int N, A, B;

    while (cin>>N && N!=0) {
        memset(vis, 0, sizeof(vis));
        cin>>A>>B;
        int i;
        for (i=1; i<=N; ++i) {
            cin>>K[i];
        }
        cout<<bfs(A, B, N)<<endl;
    }
    return 0;
}

int bfs(int low, int high, int N)
{
    queue<node>Queue;
    node Node1, Node2;
    Node1.count = 0;
    Node1.floor = low;
    vis[low] = 1;
    Queue.push(Node1);
    while (!Queue.empty()) {
        Node1 = Queue.front();
        Queue.pop();
        if (Node1.floor == high) {
            return Node1.count;
        }
        int up = Node1.floor + K[Node1.floor];
        int down = Node1.floor - K[Node1.floor];
        if (!vis[up] && up>=1 && up<=N) {
            Node2 = Node1;
            vis[up] = 1;
            Node2.floor = up;
            ++Node2.count;
            Queue.push(Node2);
        }
        if (!vis[down] && down>=1 && down<=N) {
            Node2 = Node1;
            vis[down] = 1;
            Node2.floor = down;
            ++Node2.count;
            Queue.push(Node2);
        }
    }
    return -1;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

const int maxn = 200 + 5;
int N, A, B;
int state[maxn];
bool vis[maxn];

struct Node {
    int floor;
    int Count;
}tmp;

int bfs();

int main()
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    while (cin>>N && N!=0) {
        memset(vis, false, sizeof(vis));
        cin>>A>>B;
        for (int i = 1; i <= N; ++i) {
            cin>>state[i];
        }
        cout<<bfs()<<endl;
    }
    return 0;
}

int bfs()
{
    queue<Node>Queue;
    tmp.floor = A;
    tmp.Count = 0;
    Queue.push(tmp);
    vis[A] = true;
    while (!Queue.empty()) {
        int nfloor = Queue.front().floor;
        int nCount = Queue.front().Count;
        if (nfloor == B) {
            return nCount;
        }
        Queue.pop();
        for (int i = 0; i < 2; ++i) {
            if (i == 0) {
                tmp.floor = nfloor - state[nfloor];
            } else {
                tmp.floor = nfloor + state[nfloor];
            }
            if (1 <= tmp.floor && tmp.floor <= N && !vis[tmp.floor]) {
                tmp.Count = nCount + 1;
                Queue.push(tmp);
                vis[tmp.floor] = true;
            }
        }
    }
    return -1;
}

2、POJ 3984 迷宫问题
Description
定义一个二维数组:

int maze[5][5] = {

    0, 1, 0, 0, 0,

    0, 1, 0, 1, 0,

    0, 0, 0, 0, 0,

    0, 1, 1, 1, 0,

    0, 0, 0, 1, 0,

};

它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。

Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。

Output
左上角到右下角的最短路径,格式如样例所示。

Sample Input

0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output

(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>

using namespace std;

int vis[5][5];
int maze[5][5];
int fa[5][5];

void bfs(int x, int y);
void print_path(int x, int y);

int main()
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    memset(maze, 1, sizeof(maze));
    memset(vis, 0, sizeof(vis));
    int i, j;

    for (i=0; i<5; ++i) {
        for (j=0; j<5; ++j) {
            cin>>maze[i][j];
        }
    }
    bfs(0, 0);
    print_path(4, 4);
    return 0;
}

void bfs(int x, int y)
{
    queue<int>Queue;
    Queue.push(x*5+y);
    vis[x][y] = 1;
    fa[x][y] = x*5+y;
    while (!Queue.empty()) {
        x = Queue.front()/5;
        y = Queue.front()%5;
        Queue.pop();
        if (maze[x-1][y]==0 && x-1>=0 && !vis[x-1][y]) {
            vis[x-1][y] = 1;
            Queue.push((x-1)*5+y);
            fa[x-1][y] = x*5+y;
        }
        if (maze[x+1][y]==0 && x+1<5 &&  !vis[x+1][y]) {
            vis[x+1][y] = 1;
            Queue.push((x+1)*5+y);
            fa[x+1][y] = x*5+y;
        }
        if (maze[x][y-1]==0 && y-1>=0&&  !vis[x][y-1]) {
            vis[x][y-1] = 1;
            Queue.push(x*5+y-1);
            fa[x][y-1] = x*5+y;
        }
        if (maze[x][y+1]==0 && y+1<5 &&  !vis[x][y+1]) {
            vis[x][y+1] = 1;
            Queue.push(x*5+y+1);
            fa[x][y+1] = x*5+y;
        }
    }
}

void print_path(int x, int y)
{
    stack<int>Stack;
    Stack.push(x*5+y);
    while (1) {
        int fx = fa[x][y]/5;
        int fy = fa[x][y]%5;
        if (fx==x && fy==y) {
            break;
        }
        Stack.push(fx*5+fy);
        x = fx;
        y = fy;
    }
    while (!Stack.empty()) {
        cout<<"("<<Stack.top()/5<<", "<<Stack.top()%5<<")"<<endl;
        Stack.pop();
    }
}

3、POJ 3278 Catch That Cow

Description

Farmer John has been informed of the location of a fugitive cow and wants to catch her immediately. He starts at a point N (0 ≤ N ≤ 100,000) on a number line and the cow is at a point K (0 ≤ K ≤ 100,000) on the same number line. Farmer John has two modes of transportation: walking and teleporting.

  • Walking: FJ can move from any point X to the points X - 1 or X + 1 in a single minute
  • Teleporting: FJ can move from any point X to the point 2 × X in a single minute.

If the cow, unaware of its pursuit, does not move at all, how long does it take for Farmer John to retrieve it?

Input
Line 1: Two space-separated integers: N and K

Output
Line 1: The least amount of time, in minutes, it takes for Farmer John to catch the fugitive cow.

Sample Input

5 17

Sample Output

4

Hint
The fastest way for Farmer John to reach the fugitive cow is to move along the following path: 5-10-9-18-17, which takes 4 minutes.

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <stack>

using namespace std;

int N, K;
int vis[100010];

struct node {
    int pos;
    int minute;
};

int bfs();

int main()
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);

    cin>>N>>K;
    memset(vis, 0, sizeof(vis));
    cout<<bfs()<<endl;

    return 0;
}

int bfs()
{
    queue<node>Queue;
    node Node;
    Node.pos = N;
    Node.minute = 0;
    vis[Node.pos] = 1;
    Queue.push(Node);
    while (!Queue.empty()) {
        int x = Queue.front().pos;
        int y = Queue.front().minute;
//        cout<<x<<endl;
        Queue.pop();
        if (x == K) {
            return y;
        }
        if (x-1>=0 && (!vis[x-1])) {
            vis[x-1] = 1;
            Node.pos = x-1;
            Node.minute = y+1;
            Queue.push(Node);
        }
        if (x+1<=100000 && (!vis[x+1])) {
            vis[x+1] = 1;
            Node.pos = x+1;
            Node.minute = y+1;
            Queue.push(Node);
        }
        if (x*2<=100000 && (!vis[x*2])) {
            vis[x*2] = 1;
            Node.pos = x*2;
            Node.minute = y+1;
            Queue.push(Node);
        }
    }
    return 0;
}

4、NOJ 1010 走不出的迷宫

Description:
Jack和同学在游乐园的迷宫里找不到出路了,请你帮助他们找到正确路线.
Input:

迷宫使用0和1字符表示,0表示有路1表示为墙.迷宫为正方形.左上角为(1,1),右下角为(N,N).左上角为入口,出口在(N,N).

输入第一行有3个正整数N,x,y.
N表示迷宫规模,x,y表示Jack和同学所在的迷宫位置. 要求找出从(x,y)到(N,N)的路径( N ≤ 80 ). 且出口和入口的值一定为0

下边为迷宫的字符模型用01表示.
Output:
假如找到线路,第一行输出Found下边输出迷宫模型使用´´#´´表示找到的线路.
假如未找到输出Not Found
Example Input:

6 5 2
0 0 1 1 1 1
1 0 0 0 0 1
1 1 1 0 1 1
1 0 0 0 1 1
1 0 1 0 1 1
1 0 1 0 0 0

Example Output:

Found
0 0 1 1 1 1
1 0 0 # # 1
1 1 1 # 1 1
1 0 0 # 1 1
1 0 1 # 1 1
1 0 1 # # #

Hint:
1.假定迷宫只有唯一出路,也就是说迷宫内路线宽度不超过2个字符.

#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>

using namespace std;

int N;
char maze[85][85];
int father[85][85];
int vis[85][85];

void bfs(int x, int y);
void path_paint(int x, int y);

int main()
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
    int x, y;

    while (cin>>N>>x>>y) {
        memset(vis, 0, sizeof(vis));
        memset(father, 0, sizeof(father));
        int i, j;
        for (i=0; i<N; ++i) {
            for (j=0; j<N; ++j) {
                cin>>maze[i][j];
            }
        }
        bfs(y-1, x-1);
        if (father[N-1][N-1] == 0) {
            cout<<"Not Found"<<endl;
        } else {
            path_paint(N-1, N-1);
            cout<<"Found"<<endl;
            for (i=0; i<N; ++i) {
                cout<<maze[i][0];
                for (j=1; j<N; ++j) {
                    cout<<" "<<maze[i][j];
                }
                cout<<endl;
            }
        }
    }
    return 0;
}

void bfs(int x, int y)
{
    queue<int>Queue;
    Queue.push(x*N+y);
    father[x][y] = x*N+y;
    vis[x][y] = 1;
    while (!Queue.empty()) {
        x = Queue.front() / N;
        y = Queue.front() % N;
        Queue.pop();
        if (maze[x-1][y]=='0' && (!vis[x-1][y]) && x-1>=0) {
            Queue.push((x-1)*N+y);
            father[x-1][y] = x*N+y;
            vis[x-1][y] = 1;
        }
        if (maze[x+1][y]=='0' && (!vis[x+1][y]) && x+1<N) {
            Queue.push((x+1)*N+y);
            father[x+1][y] = x*N+y;
            vis[x+1][y] = 1;
        }
        if (maze[x][y-1]=='0' && (!vis[x][y-1]) && y-1>=0) {
            Queue.push(x*N+y-1);
            father[x][y-1] = x*N+y;
            vis[x][y-1] = 1;
        }
        if (maze[x][y+1]=='0' && (!vis[x][y+1]) && y+1<N) {
            Queue.push(x*N+y+1);
            father[x][y+1] = x*N+y;
            vis[x][y+1] = 1;
        }
    }
}

void path_paint(int x, int y)
{
    maze[x][y] = '#';
    int a = father[x][y] / N;
    int b = father[x][y] % N;
    while (!(a==x&&b==y)) {
        maze[a][b] = '#';
        x = a;
        y = b;
        a = father[x][y] / N;
        b = father[x][y] % N;
    }
}

5、POJ 2251 Dungeon Master

Description
You are trapped in a 3D dungeon and need to find the quickest way out! The dungeon is composed of unit cubes which may or may not be filled with rock. It takes one minute to move one unit north, south, east, west, up or down. You cannot move diagonally and the maze is surrounded by solid rock on all sides.

Is an escape possible? If yes, how long will it take?

Input
The input consists of a number of dungeons. Each dungeon description starts with a line containing three integers L, R and C (all limited to 30 in size).
L is the number of levels making up the dungeon.
R and C are the number of rows and columns making up the plan of each level.
Then there will follow L blocks of R lines each containing C characters. Each character describes one cell of the dungeon. A cell full of rock is indicated by a ‘#’ and empty cells are represented by a ‘.’. Your starting position is indicated by ‘S’ and the exit by the letter ‘E’. There’s a single blank line after each level. Input is terminated by three zeroes for L, R and C.

Output
Each maze generates one line of output. If it is possible to reach the exit, print a line of the form

Escaped in x minute(s). 

where x is replaced by the shortest time it takes to escape.
If it is not possible to escape, print the line

Trapped! 

Sample Input

3 4 5
S....
.###.
.##..
###.#

#####
#####
##.##
##...

#####
#####
#.###
####E

1 3 3
S##
#E#
###

0 0 0

Sample Output

Escaped in 11 minute(s).
Trapped!

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>

using namespace std;

int L, R, C;
int tx, ty, tz;
const int maxn = 30 + 5;
char maze[maxn][maxn][maxn];
bool vis[maxn][maxn][maxn];
int dir[][3] = {{-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1}};

struct Node {
    int xpos, ypos, zpos;
    int Count;
}tmp;

int bfs(int x, int y, int z);

int main()
{
//    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);

    while (cin>>L>>R>>C && !(L==0&&R==0&&C==0)) {
        memset(vis, false, sizeof(vis));
        int x, y, z;
        for (int i=0; i<L; ++i) {
            for (int j=0; j<R; ++j) {
                for (int k=0; k<C; ++k) {
                    cin>>maze[i][j][k];
                    if (maze[i][j][k] == 'S') {
                        x = i; y = j; z = k;
                    }
                    if (maze[i][j][k] == 'E') {
                        tx = i; ty = j; tz = k;
                    }
                }
            }
        }
        int ret = bfs(x, y, z);
        if (ret == 0) {
            cout<<"Trapped!"<<endl;
        } else {
            cout<<"Escaped in "<<ret<<" minute(s)."<<endl;
        }
    }
    return 0;
}

int bfs(int x, int y, int z)
{
    queue<Node>Queue;
    tmp.xpos = x;
    tmp.ypos = y;
    tmp.zpos = z;
    tmp.Count = 0;
    Queue.push(tmp);
    vis[x][y][z] = 1;
    while (!Queue.empty()) {
        int nx = Queue.front().xpos;
        int ny = Queue.front().ypos;
        int nz = Queue.front().zpos;
        int nCount = Queue.front().Count;
        if (nx == tx && ny == ty && nz == tz) {
            return nCount;
        }
        Queue.pop();
        for (int i=0; i<6; ++i) {
            tmp.xpos = nx + dir[i][0];
            tmp.ypos = ny + dir[i][1];
            tmp.zpos = nz + dir[i][2];
            if (0<=tmp.xpos && tmp.xpos<L && 0<=tmp.ypos && tmp.ypos<R && 0<=tmp.zpos && tmp.zpos<C) {
                if (maze[tmp.xpos][tmp.ypos][tmp.zpos] != '#' && !vis[tmp.xpos][tmp.ypos][tmp.zpos]) {
                    tmp.Count  = nCount + 1;
                    vis[tmp.xpos][tmp.ypos][tmp.zpos] = true;
                    Queue.push(tmp);
                }
            }
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值