HDU - 3533 Escape(预处理+A*)
生活随笔
收集整理的這篇文章主要介紹了
HDU - 3533 Escape(预处理+A*)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:題意我感覺描述的很不清楚。。是看網上其他大佬的博客總結來的,大意就是我們要從點(0,0)走到點(n,m),然后在一些地方設置了炮塔(炮塔視為墻),可以向一個方向周期性地發射同一速率的炮彈,當炮彈到達某一方格的時間是整數時,說明當我們在這個時間到達這個方格時會被擊中,然后我們的行駛路線有五個方向,分別是上下左右和不動,并且可以走之前走過的路,問在上述條件下,我們到達目的地的最短時間是多少
需要補充一點,兩個炮彈若中途相遇則可以相互穿過,但是炮彈無法穿過炮塔
題目分析:我們可以發現關于炮塔在某一時間發射的炮彈的位置,該方格是無法供我們行走的,所以我們可以開一個三維的have數組用來儲存哪些狀態是無法到達的,預處理一下,然后再直接bfs深搜即可,注意因為這個題目中可以回到之前走過的位置,所以我們可以開一個三維的vis數組用來去重,很像之前做過的動態規劃+bfs的題目一樣,因為這個題目的起點和終點都是固定的,我們可以用曼哈頓距離來比較一下隊列中的優先級,就可以用A*算法優化了
上代碼吧:
#include<iostream> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<unordered_map> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=110;const int b[5][2]={0,1,0,-1,1,0,-1,0,0,0};bool book[N][N];//儲存炮塔位置bool have[N][N][1100];//儲存炮彈位置bool vis[N][N][1100];//儲存重復位置int n,m,k,time,ans;struct node//儲存炮彈信息用 {int t,v,x,y,dir; }a[N];bool check(int x,int y)//檢查邊界,注意是從0開始到n/m結束 {if(x<0||y<0||x>n||y>m||book[x][y])return false;return true; }void init()//預處理炮彈的位置 {for(int i=1;i<=k;i++)//pre{for(int j=0;j<=time;j+=a[i].t)//time{int xx=a[i].x+b[a[i].dir][0];int yy=a[i].y+b[a[i].dir][1];while(check(xx,yy)){int k=abs(xx-a[i].x)+abs(yy-a[i].y);//走了幾步 if(k%a[i].v==0)have[xx][yy][j+k/a[i].v]=true;xx+=b[a[i].dir][0];yy+=b[a[i].dir][1];}}} }struct Node//優先隊列用 {int x,y,time,rtime;Node(int X,int Y,int TIME,int RTIME){x=X;y=Y;time=TIME;rtime=RTIME;}bool operator<(const Node& a)const{return time+rtime>a.time+a.rtime;} };bool A_star() {priority_queue<Node>q;q.push(Node(0,0,0,n+m));vis[0][0][0]=true;while(!q.empty()){Node cur=q.top();q.pop();if(cur.time>time)return false;if(cur.x==n&&cur.y==m){ans=cur.time;return true;}for(int i=0;i<5;i++){int xx=cur.x+b[i][0];int yy=cur.y+b[i][1];int t=cur.time+1;if(!check(xx,yy))continue;if(vis[xx][yy][t])continue;if(have[xx][yy][t])continue;vis[xx][yy][t]=true;int rt=abs(xx-n)+abs(yy-m);q.push(Node(xx,yy,t,rt));}}return false; }int main() {while(scanf("%d%d%d%d",&n,&m,&k,&time)!=EOF){memset(book,false,sizeof(book));memset(have,false,sizeof(have));memset(vis,false,sizeof(vis));for(int i=1;i<=k;i++)//讀入炮彈信息{char dir[5];scanf("%s",dir);if(dir[0]=='E')a[i].dir=0;else if(dir[0]=='W')a[i].dir=1;else if(dir[0]=='S')a[i].dir=2;else if(dir[0]=='N')a[i].dir=3;scanf("%d%d%d%d",&a[i].t,&a[i].v,&a[i].x,&a[i].y);book[a[i].x][a[i].y]=true;}init();if(A_star())printf("%d\n",ans);elseprintf("Bad luck!\n");}return 0; }?
總結
以上是生活随笔為你收集整理的HDU - 3533 Escape(预处理+A*)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU - 1547 Bubble Sh
- 下一篇: HDU - 4394 Digital S