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 -----------\n\n");
            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\n",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\n",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\n\n", S.x, S.y );

        //printf("s=%d %d\n\n", 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\n", 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\n", come );

        ans2=right_dfs(S, come, 1);

       ans3=bfs_sp();

        printf("%d %d %d\n", ans1, ans2, ans3);

    }
    return 0;
}

 


posted @ 2015-07-30 09:38  我喜欢旅行  阅读(183)  评论(0编辑  收藏  举报