不愧是kuangbin的搜索進階,這題沒靈感寫起來好心酸php
思路是預處理全部炮臺射出的子彈,以此構造一個三維圖(其中一維是時間)node
預處理過程就至關於在圖中增長了不少不可到達的牆,而後就是一個簡單的bfsios
此題難點也是預處理過程,還有就是注意能夠停在原地也就是有5個方向spa
而後就是建圖用bool類型,否則可能會爆內存。code
http://acm.hdu.edu.cn/showproblem.php?pid=3533blog
AC: 405ms 11608kb
內存
#include<iostream> #include<sstream> #include<stack> #include<cstdio> #include<cstdlib> #include<cstring> #include<climits> #include<cctype> #include<queue> #include<algorithm> #include<cmath> #include<map> #include<set> #define inf 0x3f3f3f3f #define N 150 using namespace std; int n,m,ans,energe; //energe所給的總時間 int dir[5][2]= {{-1,0},{0,-1},{1,0},{0,1},{0,0}}; //(0,0)留在原地 bool pic[101][101][1001]; struct GUN{ short int x,y; short int dir; //炮臺方向 short int period; //炮臺發射子彈的週期 short int velocity; //子彈速度 } gun[101]; struct NODE{ short int x,y; short int eng; //當前所耗時間 }node,temp; void init(int &group) //預處理(參考HUSToj上ID爲ENDIF的代碼) { for(int i=0; i<group; ++i) { int state=0; //子彈走過的路程 int x=gun[i].x;int y=gun[i].y; int dd=gun[i].dir; while(1) { ++state; x+=dir[dd][0];y+=dir[dd][1]; if(x<0||x>n||y<0||y>m||(!pic[x][y][0])) break; //有炮臺,子彈會被阻擋 if(!(state%gun[i].velocity)) //若是子彈在整數時間內到達某可達位置 { //則進行圖的預處理(增長不可到達的「牆」) for(int j=state/gun[i].velocity; j<=energe; j+=gun[i].period) pic[x][y][j]=false; } } } } bool bfs() { queue<NODE>q; node.x=0; node.y=0; node.eng=0; q.push(node); while(!q.empty()) { node=q.front(); q.pop(); if(node.x==n&&node.y==m) { ans=node.eng; return true; } if(node.eng==energe) return false; if(n-node.x+m-node.y>energe-node.eng) continue; //曼哈頓距離剪枝 temp=node; ++temp.eng; for(int i=0; i<5; ++i) { temp.x=node.x+dir[i][0]; temp.y=node.y+dir[i][1]; if(temp.x<0||temp.x>n||temp.y<0||temp.y>m||(!pic[temp.x][temp.y][temp.eng])) continue; pic[temp.x][temp.y][temp.eng]=false; q.push(temp); } } return false; } int main() { //freopen("lxx.txt","r",stdin); int group; char ch; while(scanf("%d%d%d%d",&n,&m,&group,&energe)!=EOF) { memset(pic,true,sizeof(pic)); for(int i=0; i<group; ++i) { scanf(" %c",&ch); if(ch=='N') gun[i].dir=0; else if(ch=='W') gun[i].dir=1; else if(ch=='S') gun[i].dir=2; else gun[i].dir=3; scanf("%hd%hd%hd%hd",&gun[i].period,&gun[i].velocity,&gun[i].x,&gun[i].y); for(int j=0; j<=energe; ++j) pic[gun[i].x][gun[i].y][j]=false; } init(group); if(!bfs()) printf("Bad luck!\n"); else printf("%d\n",ans); } return 0; }
努力向高級搜索邁進!ci