标签:kill signed second init pop turn BMI ++ 思路
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2462 Accepted Submission(s): 716
4 4 3 10
N 1 1 1 1
W 1 1 3 2
W 2 1 2 4
4 4 3 10
N 1 1 1 1
W 1 1 3 2
W 1 1 2 4
Sample Output
9
Bad luck!
题意:有个人需要从(0,0)在d秒内走到(n,m),地图上有k个炮台(x,y)(具有射速,时间周期,方向),然后求是否可以在d秒内走到(n,m),能则输出时间,否则输出Bad luck!
当然炮台可以挡住其他炮台射来的子弹且不会损坏,炮台的子弹只有和人同时到达某个点时,才算击中。人可以保持五种状态上下左右原地.
思路:BFS就行,每次确定一个点时,确定其4个方向的最近炮台是否是朝这边射来的,如果是朝这边射来的话,我们判断一下我和炮台的距离,以及我们走过的时间来
判断和时间周期的关系即可。
#include<bits/stdc++.h> #define fi first #define llu unsigned long long #define pll pair<int,int> #define se second using namespace std; const int maxn = 105; bool vis[maxn][maxn][maxn*10]; int dri[5][2]= {0,1,1,0,0,-1,-1,0,0,0}; int n,m,d; struct node { int x,y,step; node(int x,int y,int step):x(x),y(y),step(step) {}; }; struct point { char s; int t,v,x,y; } s[maxn][maxn]; bool check(int x,int y) { if(x>n||x<0||y>m||y<0) return true; return false; } void bfs() { queue<node> q; q.push(node(0,0,0)); vis[0][0][0]=true; while(!q.empty()) { node u=q.front(); q.pop(); if(u.step>d) break; if(u.x==n&&u.y==m) { printf("%d\n",u.step); return ; } for(int i=0; i<5; i++) { node v = u; v.x+=dri[i][0]; v.y+=dri[i][1]; v.step+=1; if(check(v.x,v.y)||v.step>d) continue; if(!s[v.x][v.y].t&&!vis[v.x][v.y][v.step])//下一步没炮台 { bool fg=0; for(int j=v.x+1; j<=n; j++) //枚举右边的地图 { if(s[j][v.y].t&&s[j][v.y].s==‘N‘) //存在炮台,且炮台朝左边发射 { int dis=j-v.x; //距离 if(dis%s[j][v.y].v) break;//当不能整除炮弹肯定会和人擦肩而过 int tmp=v.step-dis/s[j][v.y].v;//算出炮弹射到此处的时间 if(tmp<0) break;// 炮弹还没到这里 if(tmp%s[j][v.y].t==0)//刚好能整除周期 那么就代表能打中 { fg=1; break; } } if(s[j][v.y].t) break;//如果存在一个炮台不是朝人这边射来,那么子弹都被此炮台吸收 } //其他方向同上 if(fg) continue; for(int j=v.x-1; j>=0; j--) { if(s[j][v.y].t&&s[j][v.y].s==‘S‘) { int dis=v.x-j; if(dis%s[j][v.y].v) break; int tmp=v.step-dis/s[j][v.y].v; if(tmp<0) break; if(tmp%s[j][v.y].t==0) { fg=1; break; } } if(s[j][v.y].t) break; } if(fg) continue; for(int j=v.y+1; j<=m; j++) { if(s[v.x][j].t&&s[v.x][j].s==‘W‘) { int dis=j-v.y; if(dis%s[v.x][j].v) break; int tmp=v.step-dis/s[v.x][j].v; if(tmp < 0) break; if(tmp%s[v.x][j].t==0) { fg=1; break; } } if(s[v.x][j].t) break; } if(fg) continue; for(int j=v.y-1; j>=0; j--) { if(s[v.x][j].t&&s[v.x][j].s==‘E‘) { int dis=v.y-j; if(dis%s[v.x][j].v) break; int tmp=v.step-dis/s[v.x][j].v; if(tmp < 0) break; if(tmp%s[v.x][j].t==0) { fg=1; break; } } if(s[v.x][j].t) break; } if(fg) continue; vis[v.x][v.y][v.step]=1; q.push(v); } } } printf("Bad luck!\n"); } int main() { int k; int t,c,x,y; char ch[3]; while(~scanf("%d %d %d %d",&n,&m,&k,&d)) { memset(s,0,sizeof(s)); memset(vis,false,sizeof(vis)); for(int i=1; i<=k; i++) { scanf("%s%d%d%d%d",ch,&t,&c,&x,&y); s[x][y].s=ch[0]; s[x][y].t=t; s[x][y].v=c; } bfs(); } }
PS:摸鱼怪的博客分享,欢迎感谢各路大牛的指点~
标签:kill signed second init pop turn BMI ++ 思路
原文地址:https://www.cnblogs.com/MengX/p/9368334.html