UVA10047

用一个bfs就行了,但和普通的bfs不一样的,普通的bfs条件通常是有 行和列是否访问 ,然后向8个方向拓展;而这题的变量需要有4个,行列,方向,颜色。

但写法和普通的bfs一模一样,就是vis数组成了四维。。而拓展变成了三个,左转,右转,和前进。需要特别注意的是,左转,右转还有前进的时候,哪些变量怎么变,

还有一个细节就是在用0,1,2,3标记四个方向时,左转右转怎么变,每个方向前进时,行列,x,y怎么变;;


Ac代码 :


#include<stdio.h>
#include<iostream>
#include<string>
#include<queue>
using namespace std;

const int N = 100;
int go[4][2] = {{-1,0}, {0,1}, {1,0}, {0,-1}};
int bx,by,ex,ey;
bool vis[N][N][4][5];
string str[N];
bool ok;
struct bic {
	int x;
	int y;
	int color;
	int sta;
	int sec;
}bic1,bic2;
int res;
int n,m;
int Case = 1;
queue<bic> q;
void init() {
	for (int i = 0 ; i < N ; i++) 
		str[i] = "";
	for (int i = 0 ; i < N ;i++) {
		for (int  j = 0 ; j < N ;j++) {
			for (int k = 0 ; k < 4 ; k++) {
				for (int l = 0 ;l < 5 ;l++)
					vis[i][j][k][l] = false;
			}
		}
	}
	while (!q.empty())
		q.pop();
	ok = false;
	
}
void bfs() {
	bic1.x = bx;
	bic1.y = by;
	bic1.color = 0;
	bic1.sta = 0;
	bic1.sec = 0;
	q.push(bic1);
	vis[bx][by][0][0] = true;
	while(!q.empty()) {
		bic1 = q.front();
		q.pop();
		if (bic1.x == ex && bic1.y == ey && bic1.color == 0) {
			ok = true;
			res = bic1.sec;
			return ;
		}
		bic2.x = bic1.x;
		bic2.y = bic1.y;
		bic2.color = bic1.color;
		bic2.sta = (bic1.sta + 3) % 4;
		bic2.sec = bic1.sec + 1;
		if (vis[bic2.x][bic2.y][bic2.sta][bic2.color] == false) {
			q.push(bic2);
			vis[bic2.x][bic2.y][bic2.sta][bic2.color] = true;
		}
		bic2.sta = (bic1.sta + 1) % 4;
		if (vis[bic2.x][bic2.y][bic2.sta][bic2.color] == false) {
			q.push(bic2);
			vis[bic2.x][bic2.y][bic2.sta][bic2.color] = true;
		}
		bic2.sta = bic1.sta;
		bic2.color = (bic1.color + 1) % 5;
		bic2.x = bic1.x + go[bic1.sta][0];
		bic2.y = bic1.y + go[bic1.sta][1];
		if (bic2.x >= 0 && bic2.y >= 0 && bic2.x < n && bic2.y < m && vis[bic2.x][bic2.y][bic2.sta][bic2.color] == false && str[bic2.x][bic2.y] != '#') {
			q.push(bic2);
			vis[bic2.x][bic2.y][bic2.sta][bic2.color] = true;
		}
		
		
	}

}
int main () {
	while (cin >> n >> m) {
		getchar();
		if (n == 0 && m == 0)
			break;
		init();
		for (int i = 0 ; i < n ;i++)
			getline (cin ,str[i]);
		for (int i = 0 ; i < n ; i++) {
			for (int j = 0; j < m ; j++) {
				if (str[i][j] == 'S') {
					bx = i;
					by = j;
				}
				if (str[i][j] == 'T') {
					ex = i;
					ey = j;
				}
			}
		}
		bfs();
		if (Case != 1)
			cout << endl;
		cout <<"Case #" << Case++ <<endl;
		if (ok == true)
			cout << "minimum time = "<< res <<" sec" <<endl;
		else
			cout<<"destination not reachable" <<endl;

	}

	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值