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 ;
    }
  • 相关阅读:
    Android 4 学习(21):对话框
    Android 4 学习(20):ActionBar
    Android 4 学习(19):Services
    Android 4 学习(18):搜索
    Android 4 学习(17):使用Content Resolver
    【转】Max2013脚本工具的乱码问题
    【转】巧用DOS tree命令+批处理 实现 指定文件 批量复制!
    【转】PHP 杂谈 坑爹的file_exists
    【转】MySQL:日期函数、时间函数总结(MySQL 5.X)
    【转】pam_mysql
  • 原文地址:https://www.cnblogs.com/yi-ye-zhi-qiu/p/7645530.html
Copyright © 2011-2022 走看看