POJ 3083

玩了一会再做,又1Y了。估计是题目比较基础

遗憾的一点是,我做的有点慢,1个小时的样子,以后应该快一些才行。

 

左转右转的步数直接用while 循环数出来就行。我将两个函数写成了一个。最后最短路是典型的BFS。

 

#include <iostream> #include <string> #define F(i,a,b) for (int i=a;i<=b;i++) using namespace std; class p2 { public: int x, y; p2() {} p2(int a, int b) { x=a, y=b; } bool operator == (const p2& b) const { return (x==b.x && y==b.y) ; } bool operator != (const p2& b) const { return !(*this==b); } friend ostream& operator << (ostream& os, const p2& b) { os << b.x << " " << b.y; return os; } }man, s, e, Q[1602], f[42][42]; int dir, w, h, move[4][2]={ {0,-1}, {-1,0}, {0,1}, {1,0} }; string str[42]; int add(int a, int b) { if (a+b==-1) return 3; return (a+b)%4; } bool reach(int x, int y) // reachable { return (x>=0 && x<h && y>=0 && y<w && str[x][y]!='#'); } //turn1: initial direction related to dir //turn2: turn in loop int bfs2(int turn1, int turn2) { int steps=0; while (man!=e) { steps++; dir=add(dir,turn1); F(i,1,4) { if ( reach( man.x+move[dir][0], man.y+move[dir][1] ) ) { man.x+=move[dir][0]; man.y+=move[dir][1]; break; } dir=add(dir,turn2); } } steps++; return steps; } //bfsleft: bfs2(-1, 1) bfsright: bfs2(1, -1) int steps[42][42]; bool mk[42][42]; int bfs() { int last=1, now=0, newx, newy; Q[last]=p2(s.x, s.y); mk[s.x][s.y]=true; steps[s.x][s.y]=1; while (man!=e) { man=Q[++now]; F(i,0,3) { newx=man.x+move[i][0], newy=man.y+move[i][1]; if ( reach( newx, newy ) && !mk[newx][newy]) { Q[++last]=p2( newx, newy ); steps[newx][newy]=steps[ man.x ][ man.y ] + 1; mk[ Q[last].x ][ Q[last].y ]=true; } } } return steps[e.x][e.y]; } int main() { int T; cin >> T; F(t,1,T) { cin >> w >> h; F(i,0,h-1) cin >> str[i]; //get position s, e F(i,0,h-1) { if ( str[i].find("S")!=string::npos ) s=p2(i, str[i].find("S")); if ( str[i].find("E")!=string::npos ) e=p2(i, str[i].find("E")); } man=s, dir=0; memset(mk, 0, sizeof(mk) ); cout << bfs2(-1, 1) << " "; man=s, dir=0; memset(mk, 0, sizeof(mk) ); cout << bfs2(1, -1) << " "; memset(mk, 0, sizeof(mk) ); cout << bfs() << endl; } return 0; }

你可能感兴趣的:(POJ 3083)