zoukankan      html  css  js  c++  java
  • poj 3083 Children of the Candy Corn 【条件约束dfs搜索 + bfs搜索】【复习搜索题目一定要看这道题目】

    题目地址:http://poj.org/problem?id=3083

    Sample Input

    2
    8 8
    ########
    #......#
    #.####.#
    #.####.#
    #.####.#
    #.####.#
    #...#..#
    #S#E####
    9 5
    #########
    #.#.#.#.#
    S.......E
    #.#.#.#.#
    #########

    Sample Output

    37 5 5
    17 17 9
    题目分析:T组数据,每组都会有一个起点S,一个终点E。 分别输出:左边优先搜索到E的步数 右边优先搜索到E的步数 最短步数到E
    dfs搜索时候,控制好搜索下一个节点时的先后顺序。bfs找最短路最简单。
    代码:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <math.h>
    #include <iostream>
    #include <string>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <algorithm>
    
    using namespace std;
    int n, m;
    char g[50][50];
    
    struct node
    {
        int x,y;
    }S, E;
    
    
    bool ok(int x, int y) //判断是否出了边界
    {
        if(x>=0 && x<n && y>=0 && y<m) return true;
        else return false;
    }
    
    //定义转向序列
    int d[4][2]={ {0,-1},{-1,0},{0,1},{1,0} }; //定义0 1 2 3的运动位置
                //  左     上    右     下
    //上行0  右行1  下行2  左行3
    int left_dfs(node S, int come, int path)//左优先dfs
    {
        node cur=S; int e;
    
        for(int i=0; i<4; i++){
            e=(i+come)%4;
            int x=cur.x+d[e][0];
            int y=cur.y+d[e][1];
    
            if(!ok(x,y)) continue;
            if(x==E.x && y==E.y){
                //printf("dao da le -----------
    
    ");
                return path+1;
            }
            if(g[x][y]=='#') continue;
    
            if(x==cur.x && y!=cur.y)
                { if(y>cur.y) come=1; else come=3; }
            else if(x!=cur.x && y==cur.y)
                { if(x>cur.x)come=2; else come=0; }
    
            node cc; cc.x=x; cc.y=y;
            return left_dfs(cc, come, path+1);
        }
    }
    
    int d2[4][2]={ {0,1},{-1,0},{0,-1},{1,0} }; //定义0 1 2 3的运动位置
                 // 右     上     左     下
    int right_dfs(node S, int come, int path)
    {
        node cur=S; int e;
        for(int i=0; i<4; i++){
            e=(i+3+come)%4;
            int x=cur.x+d2[e][0];
            int y=cur.y+d2[e][1];
            //printf("x=%d y=%d
    ",x+1, y+1);
    
            if(!ok(x,y) ) continue;
            if(x==E.x && y==E.y){
                    //printf("*****");
                return path+1;
            }
            if(g[x][y]=='#') continue;
    
            if(x==cur.x && y!=cur.y)
                {if(y>cur.y) come=0; else come=2; }
            else if(x!=cur.x && y==cur.y)
                {if(x>cur.x) come=3; else come=1; }
    
            node cc; cc.x=x; cc.y=y;
            //printf("come=%d x=%d y=%d
    ",come, x+1, y+1);
            return right_dfs(cc, come, path+1);
        }
    }
    
    
    
    int dir[4][2]={
        {-1,0}, {1,0}, {0,-1}, {0,1} //定义 上下左右
    };
    int bfs_sp()
    {
        queue<node>q;
        int path[50][50]; memset(path, 0, sizeof(path));
        bool vis[50][50]; memset(vis, false, sizeof(vis)); //标记节点是否走过
        q.push(S);//将起点入队列
        vis[S.x][S.y]=true;//标记访问
        path[S.x][S.y]++;
        node cur;
        while(!q.empty())
        {
            cur=q.front(); q.pop();//取出队首元素
            //printf("%d--%d ", cur.x, cur.y);
            for(int i=0; i<4; i++){
                int x=cur.x+dir[i][0];
                int y=cur.y+dir[i][1];
                if(ok(x, y) && (g[x][y]=='.'||g[x][y]=='E') && vis[x][y]==false )
                {   node cc; cc.x=x; cc.y=y;
                    q.push(cc); path[x][y]=path[cur.x][cur.y]+1;
                    vis[x][y]=true;
                    if(g[x][y]=='E')
                        { return path[x][y];}
                }
            }
        }
    }
    
    int main()
    {
        int tg; scanf("%d", &tg);
        int i, j;
        //输出左优先搜索+右优先搜索+最短路径
        int ans1, ans2, ans3;
    
        while(tg--){
            scanf("%d %d", &m, &n); //n行 m列
            for(i=0; i<n; i++){
                scanf("%s", g[i]);
                for(j=0; j<m; j++){
                    if(g[i][j]=='S'){ S.x=i; S.y=j; } //找到起点
                    else if(g[i][j]=='E') { E.x=i; E.y=j; } //找到终点
                }
            } //建图完毕
            //printf("s=%d %d
    
    ", S.x, S.y );
    
            //printf("s=%d %d
    
    ", E.x, E.y );
            //一开始S可以走的方向
            int come; //标记运动方向
            for(i=0; i<4; i++){
                int x=S.x+d[i][0];
                int y=S.y+d[i][1];
                if(ok(x,y)&& g[x][y]!='#'){
                    if(i==0) come=3; //左
                    else if(i==1) come=0;//上
                    else if(i==2) come=1;//右
                    else come=2;//下
                }
            }
            //printf("come=%d
    ", come );
    
            ans1=left_dfs(S, come, 1);
    
            if(come==0) come=1;
            else if(come==1) come=0;
            else if(come==2) come=3;
            else if(come==3) come=2;
            //printf("come=%d
    ", come );
    
            ans2=right_dfs(S, come, 1);
    
           ans3=bfs_sp();
    
            printf("%d %d %d
    ", ans1, ans2, ans3);
    
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    Mysql注入绕过姿势
    轻松入侵我学校网站
    华科机考:矩阵转置
    浙大patB习题的一点总结
    链表的一些基本操作
    关于C中函数传参的一点理解
    Java与JavaScript中判断两字符串是否相等的区别
    Jsp中out.println()与System.out.println()的区别
    eclipse背景主题
    Kruskal算法的简单实现
  • 原文地址:https://www.cnblogs.com/yspworld/p/4688239.html
Copyright © 2011-2022 走看看