题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3698
题意自己google翻译。
明显的给出了monster,tower各个属性,这肯定是要建类。
不过要注意的细节是移动方式。
dir[8][2]= {0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1}
到了搜索路径的时候实际作用的其实是dir[][](0~3).
queue注意是x,y方向搜索。
其他一些判重之类没什么好讲。中等水题,需要的是无尽的耐心和细心。享受孤独,以及TLE剪纸之后WA的心情(笑)fascinating!
AC代码:
#include<iostream> #include<cstring> #include<cstdio> #include<string> #include<algorithm> #include<queue> #include<utility> using namespace std; #define ll long long char mm[60][60]; //int dir[8][2]= {0,1,0,-1,1,0,-1,0,1,1,1,-1,-1,1,-1,-1}; int dx[8]={0,0,1,-1,1,1,-1,-1}; int dy[8]={1,-1,0,0,1,-1,1,-1}; int sx,sy,tx,ty,tott,totm,totmm; int n,m,Hp,tot,to[60][60][2],dis[60][60]; struct monster { int x,y,hp,t; bool need,ice; void born(int a) { x=sx; y=sy; t=a; hp=Hp; need=ice=0; } void move() { if(need)hp-=10; if(ice) { ice=0; return; } int nx=to[x][y][0],ny=to[x][y][1]; x=nx; y=ny; } friend bool operator < (monster m1,monster m2) { if(m1.hp>0&&m2.hp>0) { if(m1.x==m2.x&&m1.y==m2.y) { return m1.t<m2.t; } return dis[m1.x][m1.y]<dis[m2.x][m2.y]; } return m1.hp>m2.hp; } } mon[60],tmm[60]; struct tower { int x,y; char typ; tower(int a,int b,char ty) { x=a; y=b; typ=ty; } tower(){} bool in(int mx,int my) { for(int i=0; i<8; i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(nx==mx&&ny==my)return 1; } return 0; } void attack() { if(typ=='B') { for(int i=0; i<totm; i++) if(in(mon[i].x,mon[i].y)) { mon[i].hp-=10; break; } } if(typ=='F') { for(int i=0; i<totm; i++) if(in(mon[i].x,mon[i].y)) { mon[i].hp-=10; } } if(typ=='N') { for(int i=0; i<totm; i++) if(in(mon[i].x,mon[i].y)) { mon[i].need=1; break; } } if(typ=='I') { for(int i=0; i<totm; i++) if(in(mon[i].x,mon[i].y)) { mon[i].ice=1; break; } } } }tow[60]; bool check(int x,int y) { if(!(x>=0&&x<n&&y>=0&&y<m))return 0; if(mm[x][y]!='.'&&mm[x][y]!='T'&&mm[x][y]!='S')return 0; return 1; } void route() { memset(to,-1,sizeof(to)); memset(dis,-1,sizeof(dis)); queue<int>q[2]; to[tx][ty][0]=tx; to[tx][ty][1]=ty; dis[tx][ty]=0; q[0].push(tx); q[1].push(ty); while(!q[0].empty()) { int x=q[0].front(); q[0].pop(); int y=q[1].front(); q[1].pop(); for(int i=0; i<4; i++) { int nx=x+dx[i]; int ny=y+dy[i]; if(!check(nx,ny))continue; if(to[nx][ny][0]!=-1)continue; to[nx][ny][0]=x; to[nx][ny][1]=y; dis[nx][ny]=dis[x][y]+1; q[0].push(nx); q[1].push(ny); } } } void born(int a) { mon[totm++].born(a); } void clcmon() { sort(mon,mon+totm); for(int i=0; i<totm; i++) { if(mon[i].hp<=0) { totm=i; break; } } } bool checklose() { for(int i=0; i<totm; i++) { if(mon[i].x==tx&&mon[i].y==ty) return 1; } return 0; } bool move(int now) { for(int i=0; i<totm;i++)mon[i].move(); if(now<=tot)born(now); clcmon(); return checklose(); } void attack() { for(int i=0; i<tott; i++) { tow[i].attack(); } } bool judge(monster m1,monster m2) { if(m1.x!=m2.x)return 0; if(m1.y!=m2.y)return 0; if(m1.ice!=m2.ice)return 0; if(m1.need!=m2.need)return 0; if(m1.hp!=m2.hp)return 0; return 1; } bool same() { if(totmm!=totm)return 0; for(int i=0; i<totm;i++)if(!judge(tmm[i],mon[i])) return 0; return 1; } int main() { int t; cin>>t; while(t--) { cin>>n>>m>>tot>>Hp; for(int i=0; i<n; i++) cin>>mm[i]; totm=tott=0; for(int i=0; i<n; i++) for(int j=0; j<m; j++) { if(mm[i][j]=='S') { sx=i; sy=j; } else if(mm[i][j]=='T') { tx=i; ty=j; } else if(mm[i][j]=='B') { tow[tott++]=tower(i,j,'B'); } else if(mm[i][j]=='F') { tow[tott++]=tower(i,j,'F'); } else if(mm[i][j]=='N') { tow[tott++]=tower(i,j,'N'); } else if(mm[i][j]=='I') { tow[tott++]=tower(i,j,'I'); } } route(); int ans=0; while(1) { ans++; if(move(ans)) { ans=-1; break; } attack(); clcmon(); if(ans>=tot&&totm==0)break; if(ans>tot&&same()) { ans=-1; break; } for(int i=0;i<totm;i++) tmm[i]=mon[i]; totmm=totm; } cout<<ans<<endl; } }
interesting!不愧我Y。