宽搜 --- 流星雨题解

题目及提交:http://www.rqnoj.cn/Problem_335.html

 

这道题目明显需要使用宽搜,要先预处理出安全的地点,还有边界问题,不能只开300的数组,因为虽然只有300以内会被轰炸,但是Bessie可以继续往外跑,数组开小了有一个点过不去。

 

普通的宽搜就能过。

 

#include using namespace std; const int _DEF_MAXNUM = 0x7fffffff; struct _cinfo { int x,y,t; }; int _gm,_gdist[310][310],_gqs; int _gsafe[310][310]; //安全标志 _DEF_MAXNUM则为安全 否则表示在什么时刻被摧毁 _cinfo _gqueue[100000]; //链表 int _gdirect_r[] = { -1,0,1,0 }; int _gdirect_l[] = { 0,1,0,-1 }; inline bool _fjudge( int x,int y ) { if( x < 0 || y < 0 ) return false; return true; } void _finit() { _gqs = 0; for( int i = 0;i < 310;++i ) { for( int j = 0;j < 310;++j ) _gsafe[i][j] = _gdist[i][j] = _DEF_MAXNUM; } cin >> _gm; int tx,ty,x,y,t; for( int i = 0;i < _gm;++i ) { cin >> x >> y >> t; //标志为不安全 if( t < _gsafe[ x ][ y ] ) _gsafe[ x ][ y ] = t; for( int j = 0;j < 4;++j ) { tx = x + _gdirect_r[j]; ty = y + _gdirect_l[j]; if( _fjudge( tx,ty ) ) { if( t < _gsafe[tx][ty] ) _gsafe[tx][ty] = t; } } } _gqueue[ _gqs ].x = _gqueue[ _gqs ].y = _gqueue[ _gqs ].t = 0; //起始点 ++_gqs; _gdist[0][0] = 0; } int main() { _finit(); int begin = 0; while( begin < _gqs ) { int x = _gqueue[ begin ].x,y = _gqueue[ begin ].y,tx,ty; ++begin; int d = _gdist[x][y] + 1; //到此点的时间 for( int i = 0;i < 4;++i ) { tx = x + _gdirect_r[i]; ty = y + _gdirect_l[i]; if( !_fjudge( tx,ty ) || _gsafe[tx][ty] <= d ) //不合法或者被摧毁了 continue; if( _gsafe[tx][ty] == _DEF_MAXNUM ) //安全地点 { cout << d << endl; return 0; } if( d < _gdist[tx][ty] ) //没有走过 入队 { _gdist[tx][ty] = d; _gqueue[ _gqs ].x = tx; _gqueue[ _gqs ].y = ty; ++_gqs; } } } cout << -1 << endl; return 0; }  

你可能感兴趣的:(搜索)