zoukankan      html  css  js  c++  java
  • kuangbin专题一:K题,POJ3984:迷宫问题(水)

    POJ3984:迷宫问题
    kuangbin专题一:K题
    题目链接:http://poj.org/problem?id=3984
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 24994   Accepted: 14597

    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)
    思路:最先想到深度优先搜索 并用结构数组存放最优路径
      后来想到数组模拟 广度优先搜索
    /*Source Code 深度优先搜索实现
    Problem: 3984        User: 201616040106
    Memory: 208K        Time: 0MS
    Language: C++        Result: Accepted
    
        Source Code*/
    
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    
    using namespace std ;
    
    #define maxn 10
    bool visit[maxn][maxn] ;//标记 
    int map[maxn][maxn] ;//地图 
    struct node {
        int x ;
        int y ;
    };
    
    node result[maxn*10] ; // 存放最优解 结构数组 
    node path[maxn*10] ;// 当前搜索路径 
    node starts ;
    int total ;
    int dirx[] = {0 , 0 , 1 , -1 } ;// 转向 
    int diry[] = {1 , -1 , 0 , 0 } ;
    
    bool check(int x , int y) {
        if(x>=0&&x<5&&y>=0&&y<5&&map[x][y]!=1&&!visit[x][y])
            return true ;
        return false ;
    }
    
    void DFS(node Q , int step) {
        if(step > total) { // 不符合最优解条件 
            return;
        }
        if(Q.x==4&&Q.y==4) { // 找到结果 逐渐修改最优解 
            if(step < total) {
                total = step ;
                for(int i=0 ; i<total ; i++) {
                    result[i] = path[i] ;
                }
            }
        }
        node turn ;
        for(int i=0 ; i<4 ; i++) {
            turn.x = Q.x + dirx[i] ;
            turn.y = Q.y + diry[i] ;
            if(check(turn.x , turn.y)) {
                visit[turn.x][turn.y] = true ;//向前搜索 
                path[step] = turn ;
                DFS(turn , step+1) ;
                visit[turn.x][turn.y] = false ;//回溯 
            }
        }
    
    
        return;
    }
    
    int main() {
    
        for(int i=0 ;  i<5 ; i++) {
            for(int j=0 ; j<5 ; j++) {
                scanf("%d" ,&map[i][j]) ;
            }
        }
        
        memset(visit , false , sizeof(visit)) ;
        total = 10000000 ;
        starts.x = 0 ;
        starts.y = 0 ;
        DFS(starts , 0 ) ;
        visit[0][0] = true ;
    
        printf("(0, 0)
    ") ;
        for(int i=0 ; i<total ; i++) {
            printf("(%d, %d)
    " , result[i].x , result[i].y) ;
        }
    
        return 0 ;
    }

    广度优先搜索实现

    /*Source Code
    Problem: 3984        User: 201616040106
    Memory: 208K        Time: 0MS
    Language:
    C++        Result:
    Accepted
    
    Source Code*/
    
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    
    using namespace std ;
    
    #define maxn 10
    bool visit[maxn][maxn] ;
    int map[maxn][maxn] ;
    int dirx[] = {0 , 0 , -1 , 1 } ;
    int diry[] = {1 , -1 , 0 , 0 } ;
    
    struct node {
        int x ;
        int y ;
        int pre ; // 记录前件 位置
    };
    
    node  path[maxn*10] ;
    
    bool check(node turn ) {
        if(turn.x>=0 && turn.x<=4 && turn.y>=0 && turn.y<=4) {
            return true ;
        }
        return false ;
    }
    
    void print(int pos) {
        if(path[pos].pre != -1) {
            print(path[pos].pre) ;
            printf("(%d, %d)
    " , path[pos].x , path[pos].y) ;
        }
        return;
    }
    
    void BFS() {
        int Front = 0 ;
        int head = 1 ;
        path[Front].x = 0 ;
        path[Front].y = 0 ;
        path[Front].pre = -1 ; // 回溯输出终止条件
    
        node turn ;
        //    数组模拟 BFS 队列操作  并用结构体记录前件  输出时顺序回溯输出  
        while(Front < head ) {
    
            for(int i=0 ; i<=3 ; i++) {
                turn.x = dirx[i] + path[Front].x ;
                turn.y = diry[i] + path[Front].y ;
                turn.pre = Front ;
                if(check(turn) && !visit[turn.x][turn.y] && map[turn.x][turn.y]!=1) {
                    visit[turn.x][turn.y] = true ;
                    path[head++] = turn ;
                }
            }
    
            if(path[Front].x == 4 && path[Front].y ==4 ) {
                printf("(0, 0)
    ") ;
                print(Front) ;
    
                break ;
            }
    
            Front++ ;
        }
        return;
    }
    
    int main() {
        while(~scanf("%d" , &map[0][0])) {
            for(int i=1 ; i<=4 ; i++) {
                scanf("%d" , &map[0][i]) ;
            }
            for(int i=1 ; i<=4 ; i++) {
                for(int j=0 ; j<=4 ; j++) {
                    scanf("%d" , &map[i][j]) ;
                }
            }
            memset(visit , false , sizeof(visit)) ;
            BFS() ;
    
        }
        return 0 ;
    }
  • 相关阅读:
    0309. Best Time to Buy and Sell Stock with Cooldown (M)
    0621. Task Scheduler (M)
    0106. Construct Binary Tree from Inorder and Postorder Traversal (M)
    0258. Add Digits (E)
    0154. Find Minimum in Rotated Sorted Array II (H)
    0797. All Paths From Source to Target (M)
    0260. Single Number III (M)
    0072. Edit Distance (H)
    0103. Binary Tree Zigzag Level Order Traversal (M)
    0312. Burst Balloons (H)
  • 原文地址:https://www.cnblogs.com/yi-ye-zhi-qiu/p/7645530.html
Copyright © 2011-2022 走看看