UVA 10047 The Monocycle (bfs)

3 篇文章 0 订阅
2 篇文章 0 订阅

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=19491


题意:给一个m*n的图和一个五色的轮子,要将其从S点转到T点,每次旋转72°,即每次旋转换一种颜色与地面接触,在每个格子(x , y)上的操作只有三种:

1. 往前走 

2. 左转

3. 右转

以上3个操作每个耗时1s,已知在S点时轮子是绿色的72°与地面接触,要求在T点也是绿色着地,求最短的时间。


思路:宽搜(广搜)。对每个点有4*5(4个方向5种颜色)个状态, 又有三条边,分别对应3个操作,时间复杂度O(60*m*n)。要开一个m*n*4*5的数组记录每个点的状态。


代码:

#include<bits/stdc++.h>
using namespace std;
struct node{
    int x, y, d, t, c;
    node(int _x = 0, int _y = 0, int _d = 0, int _t = 0, int _c = 0):x(_x),y(_y),d(_d),t(_t),c(_c){}
}S, T;
int n, m, vis[30][30][4][5], ans;
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};//  N,E,S,W分别对应0,1,2,3,方便下面操作
char a[30][30];
void bfs(node now){
    queue<node> q;
    while(!q.empty()) q.pop();
    q.push(now);
    while(!q.empty()){
        node u = q.front();
        q.pop();
        if(u.x == T.x && u.y == T.y && u.c == 0){
            ans = u.t;
            return;
        }
        int nx = u.x + dx[u.d];
        int ny = u.y + dy[u.d];
        if(nx>=0&&nx<n&&ny>=0&&ny<m&&a[nx][ny]!='#'){  //  前进
            if(!vis[nx][ny][u.d][(u.c+1)%5]){
                vis[nx][ny][u.d][(u.c+1)%5] = 1;
                q.push(node(nx, ny, u.d, u.t+1, (u.c+1)%5));
            }
        }
        if(!vis[u.x][u.y][(u.d+3)%4][u.c]){           // 左转
            vis[u.x][u.y][(u.d+3)%4][u.c] = 1;
            q.push(node(u.x, u.y, (u.d+3)%4, u.t+1, u.c));
        }
        if(!vis[u.x][u.y][(u.d+1)%4][u.c]){           // 右转
            vis[u.x][u.y][(u.d+1)%4][u.c] = 1;
            q.push(node(u.x, u.y, (u.d+1)%4, u.t+1, u.c));
        }
    }
}
int main(){
    int tc = 0;
    while(~scanf("%d %d",&n, &m)){
        if(!(n||m)) break;
        memset(vis, 0, sizeof(vis));
        ans = 0;
        if(tc) printf("\n");
        for(int i = 0; i < n; i++){
            scanf("%s", a[i]);
            for(int j = 0; j < m; j++){
                if(a[i][j] == 'S') S = node(i,j,0,0,0);
                if(a[i][j] == 'T') T = node(i,j,0,0,0);
            }
        }
        bfs(S);
        printf("Case #%d\n", ++tc);
        if(ans) printf("minimum time = %d sec\n", ans);
        else printf("destination not reachable\n");
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值