uva 10047 - The Monocycle

点击打开链接uva 10047


思路:bfs
分析:
1 题目给定一个起始的状态然后要求是否可以到达目标状态
2 这些状态包括了位置,方向,底面颜色。所以我们在每一个结点里面保存的是当前结点的位置和方向和底面的颜色,然后进行搜索
3 到达某一个格子后,我们会有三种选择前进,向左,向右,所以我们只需要去把所有符合条件的状态加入队列即可

代码:

#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

//规定北东南西为0,1,2,3
//规定五个颜色绿,白,蓝,红,黑分别为0,1,2,3,4
//如果方向是-1表示四个方向都可以
const int MAXN = 30;
const int INF = 0x3f3f3f3f;
struct Node{
    int x;
    int y;
    int t;
    int d;
    int color;
    void operator=(Node s){
        x = s.x; 
        y = s.y;
        d = s.d;
        color = s.color;
    }
};
Node end;
queue<Node>q;
int n , m , tx , ty;
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
char maze[MAXN][MAXN];
bool vis[MAXN][MAXN][10][10];

//判断是否到达最终的状态
bool isAns(Node tmp){
    if(tmp.x == end.x && tmp.y == end.y && tmp.color == end.color)
        return true;
    return false;
}

//判断点是否在地图之内
bool isOk(int x , int y){
    if(x >= 0 && x < n && y >= 0 && y < m) 
        return true;
    return false;
}

//求tx和ty
void getNext(int x , int y , int i){
    tx = x + dir[i][0]; 
    ty = y + dir[i][1];
}

int solve(){
    while(!q.empty()){
        Node tmp = q.front();
        q.pop();
        if(isAns(tmp)) 
            return tmp.t;
        //求出在当前方向上的tx和ty
        getNext(tmp.x , tmp.y , tmp.d);
        //可以进行前进
        if(isOk(tx , ty)){
            if(maze[tx][ty] != '#' && !vis[tx][ty][tmp.d][(tmp.color-1+5)%5]){
                vis[tx][ty][tmp.d][(tmp.color-1+5)%5] = true;
                q.push((Node){tx,ty,tmp.t+1,tmp.d,(tmp.color-1+5)%5}); 
            }
        }
        //如果不能前进则进行左右转
        //向左
        if(!vis[tmp.x][tmp.y][(tmp.d-1+4)%4][tmp.color]){ 
            q.push((Node){tmp.x,tmp.y,tmp.t+1,(tmp.d-1+4)%4,tmp.color}); 
            vis[tmp.x][tmp.y][(tmp.d-1+4)%4][tmp.color] = true; 
        }
        //向右 
        if(!vis[tmp.x][tmp.y][(tmp.d+1)%4][tmp.color]){ 
            q.push((Node){tmp.x,tmp.y,tmp.t+1,(tmp.d+1)%4,tmp.color}); 
            vis[tmp.x][tmp.y][(tmp.d+1)%4][tmp.color] = true; 
        }
    }
    return INF;
}

int main(){
    int Case = 1;
    bool isFirst = true;
    while(scanf("%d%d%*c" , &n , &m) && n+m){
        while(!q.empty()) 
            q.pop();
        memset(vis , false , sizeof(vis));
        if(isFirst)
            isFirst = false;
        else
            printf("\n");
        for(int i = 0 ; i < n ; i++){
            gets(maze[i]);
            for(int j = 0 ; j < m ; j++){
                if(maze[i][j] == 'S'){
                    q.push((Node){i , j , 0 , 0 , 0});
                    vis[i][j][0][0] = true; 
                }
                if(maze[i][j] == 'T')
                    end = (Node){i , j , -1 , -1 , 0};
            }
        }
        int ans = solve();
        printf("Case #%d\n" , Case++);
        if(ans != INF)
            printf("minimum time = %d sec\n" , ans);
        else
            printf("destination not reachable\n");
    }
    return 0;
}



你可能感兴趣的:(uva)