uva 10047 The Monocycle

题目:The Monocycle


思路:bfs。


代码:

#include<bits/stdc++.h>
using namespace std;

#define maxn 25

int n,m;
bool g[maxn+5][maxn+5];	//地图

struct Pair {
	int x,y;
	Pair(int xx=0,int yy=0) {
		x=xx,y=yy;
	}
	bool operator <(const Pair& oth) const {
		return x<oth.x||(x==oth.x&&y<oth.y);
	}
	bool operator ==(const Pair& oth) const {
		return x==oth.x&&y==oth.y;
	}
	bool Out() {
		return x<0||x>=n||y<0||y>=m;
	}
};

Pair Start,End;

struct State {
	Pair pos;
	int col;	//颜色
	int stp;	//时间
	int dir;	//方向
	State(Pair p,int c=0,int s=0,int d=0) {
		pos=p,col=c,stp=s,dir=d;
	}
	bool operator < (const State& oth) const {
		return pos<oth.pos||(pos==oth.pos&&(col<oth.col||(col==oth.col&&dir<oth.dir)));
	}
	bool judge() {
		return pos==End&&col==0;
	}
	int nxtc() {
		return (col+1)%5;
	}
	int nxtd() {
		return (dir+1)%4;
	}
	int lstd() {
		return (dir+4-1)%4;
	}
};

char readin() {
	char x;
	while(~(x=getchar())&&!(isalpha(x)||x=='.'||x=='#'));
	return x;
}

const int m1[5]= {-1,0,1,0};	//北东南西
const int m2[5]= {0,1,0,-1};

queue<State> q;
set<State> st;

int bfs() {
	State IN=State(Start);
	q.push(IN);
	st.insert(IN);

	while(!q.empty()) {
		State h=q.front();
		q.pop();
		
		//移动
		int i=h.dir;
		Pair p=Pair(h.pos.x+m1[i],h.pos.y+m2[i]);
		if(!p.Out()&&!g[p.x][p.y]) {
			State t=State(p,h.nxtc(),h.stp+1,i);
			if(st.find(t)==st.end()) {
				q.push(t);
				st.insert(t);
				if(t.judge()) return t.stp;
			}
		}

		//改变方向
		State t1=State(h.pos,h.col,h.stp+1,h.nxtd());
		State t2=State(h.pos,h.col,h.stp+1,h.lstd());
		if(st.find(t1)==st.end()) {
			q.push(t1);
			st.insert(t1);
		}
		if(st.find(t2)==st.end()) {
			q.push(t2);
			st.insert(t2);
		}
	}

	return -1;
}

void init() {
	queue<State> emp;
	q=emp;
	st.clear();
}

int main() {
	int T=0;
	while(~scanf("%d%d",&n,&m)&&n&&m) {
		init();

		for(int i=0; i<n; i++) {
			for(int j=0; j<m; j++) {
				char x=readin();
				if(x=='#') g[i][j]=1;
				else g[i][j]=0;
				if(x=='S') Start=Pair(i,j);
				if(x=='T') End=Pair(i,j);
			}
		}

		int ans=bfs();
		
		if(T) printf("\n");
		printf("Case #%d\n",++T);
		if(~ans) {
			printf("minimum time = %d sec\n",ans);
		} else {
			printf("destination not reachable\n");
		}
	}

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值