您的位置:首页 > 其它

The Monocycle-uva 多状态DFS遍历

2014-03-29 10:23 387 查看
这题的话就是多状态记录的DFS遍历。。。自己一开始不会,上网找的大神的解题报告最后写出来了,值得注意的就是转身要和走路分开,一步只能转或者走,不能又走又转

#include<cstdio>
#include<queue>
#include<string.h>
#include<stdlib.h>
#include<iostream>
#define  MAX_SIZE 50
using namespace std;
int m,n;
char maps[MAX_SIZE][MAX_SIZE];
int visa[MAX_SIZE][MAX_SIZE][5][4];/*分别代表坐标,颜色,方向*/
int start_x,start_y;
int end_x,end_y;
int dir_x[]={-1,1,0,0};
int dir_y[]={0,0,-1,1};
int cases;
int ok,mins;
/*next=1代表上一个样例是成功的*/
/*上、下、左、右*/
/*定义起点和终点*/
struct step
{
    int x;
    int y;
    int time;/*时间*/
    int dir;/*方向0,1,2,3表示上、下、左、右*/
    int color;
    friend bool operator < (const step &a,const step &b){
         return a.time>b.time;
    }
};
struct step start,p1,p2;
void dfs()
{
    priority_queue<step>S;
    while(!S.empty())
        S.pop();
    start.x=start_x;
    start.y=start_y;
    start.time=0;
    start.dir=0;
    start.color=0;
    S.push(start);
    /*初始化起点*/
    visa[start_x][start_y][0][0]=1;
    while(!S.empty()){
        p1=S.top();
        S.pop();
        for(int i=0;i<4;i++){
            int nx,ny;
            int color_t;
            color_t=(p1.color+1)%5;
            nx=p1.x+dir_x[i];
            /*i 0、1、2、3代表走上下左右*/
            ny=p1.y+dir_y[i];
            if(nx>=0&&ny>=0&&nx<m&&ny<n&&maps[nx][ny]!='#'){
                if(i==p1.dir)/*如果方向相同的话直接走*/{
                    p2.x=nx;
                    p2.y=ny;
                    p2.color=color_t;
                    p2.time=p1.time+1;
                    p2.dir=i;
                }
                else /*如果方向不同的只能转动了*/
                {
                    int dirs=p1.dir;
                    if((i==0&&dirs==1)||(i==1&&dirs==0)||(i==2&&dirs==3)||(i==3&&dirs==2))
                    p2.time=p1.time+2;
                    else
                    p2.time=p1.time+1;
                    p2.x=p1.x;
                    p2.y=p1.y;
                    p2.color=p1.color;
                    p2.dir=i;
                }
                if(!visa[p2.x][p2.y][p2.color][p2.dir])
                {
                    if(p2.x==end_x&&p2.y==end_y&&!p2.color)
                    {
                        ok=1;
                        mins=mins<p2.time?mins:p2.time;
                    }
                    visa[p2.x][p2.y][p2.color][p2.dir]=1;
                    S.push(p2);
                }
            }
        }
    }
    if(ok){
        printf("Case #%d\n",cases);
        printf("minimum time = %d sec\n",mins);
        return;
    }
    else {
    printf("Case #%d\n",cases);
    printf("destination not reachable\n");
    return ;
    }
}
/*定义起点和终点*/
void find_s_e() /*找到起点和终点*/
{
     int ok1=0,ok2=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
            if(maps[i][j]=='S'){
                ok1=1;
                start_x=i;
                start_y=j;
            }
            if(maps[i][j]=='T'){
                ok2=1;
                end_x=i;
                end_y=j;
            }
        }
        if(ok1&&ok2) return ;
    }
}
int main()
{
    for(cases=1;scanf("%d%d",&m,&n);cases++)
    { /*迷宫有m行n列*/
        getchar();
        mins=99999;ok=0;
        memset(visa,0,sizeof(visa));
        memset(maps,0,sizeof(maps));
        if(!m&&!n) break;
        for(int i=0;i<m;i++)
         scanf("%s",maps[i]);
         find_s_e();
         if(cases>1)
         printf("\n");
         dfs();
         /*开始遍历找点*/
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: