CSPfinal 2018安全
• 對於第1個子任務,因爲全部玩家都在安全區內,直接輸出玩家初始生命值便可;spa
• 對於第2個和第4個子任務,因爲數據量較小,能夠從玩家開始向安全區作路徑搜索;code
• 對於第3個和第5個子任務,因爲數據量較大,能夠從安全區作一次路徑搜索;orm
• 每回合開始清除安全區內的障礙物,每回合結束恢復安全區內的障礙物;xml
• 玩家不能進入障礙物的方格;blog
if(abstacles[xnew][ynew]==1) return;隊列
• 也不能穿越兩個斜向相鄰障礙物方格的間隙;ci
if(abstacles[xold][ynew]&&abstacles[xnew][yold]==1) return;get
把全部安全區的點放入隊列,bfs,獲得初始點到安全區的最短距離。string
題目保證每一個玩家給出的目標座標必定在安全區域之內。保證在任意回合,對於任意玩家,都存在一條到達本回合目標位置的移動路線
因此本次的最短距離即爲本輪該玩家的扣血量。
if(!vis[np.x][np.y]&&dat(np)&&(!(i&1)||dat(cp+dir[i-1])||dat(cp+dir[i+1])))
簡明而清晰的判斷下一個點是否可達,下一個點是否出界
#include<queue> #include<cstdio> #include<cstring> const int N=400+5; const int M=1e5+5; int n,m,ne,f,h,r,hp[M],dis[N][N]; bool data[N][N],vis[N][N]; template <typename T> inline void read(T &x){ T f=1;char ch=getchar();x=0; while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} x*=f; } struct Point{ int x,y; Point(int _x=0,int _y=0):x(_x),y(_y){} inline void Read(){ read(x);read(y);x++;y++; } inline int sqr(){ return x*x+y*y; } inline Point operator +(const Point &a) const{ return Point(x+a.x,y+a.y); } inline Point operator -(const Point &a) const{ return Point(x-a.x,y-a.y); } }pos[M],cent; const Point dir[]={ Point(0, 1), Point(1, 1), Point(1, 0), Point(1, -1), Point(0, -1), Point(-1, -1), Point(-1, 0), Point(-1, 1), Point(0, 1) }; inline void Init(){ read(n);read(m);read(ne);read(f);read(h); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) data[i][j]=1; for(int i=1;i<=ne;i++){ Point p;p.Read(); data[p.x][p.y]=0; } for(int i=1;i<=m;i++) pos[i].Read(); for(int i=1;i<=m;i++) hp[i]=h; } inline bool dat(const Point& a){ return data[a.x][a.y]; } inline void bfs(){ std::queue<Point>q; memset(vis,0,sizeof vis); for(int i=std::max(1,cent.x-r),rx=std::min(n,cent.x+r);i<=rx;i++){ for(int j=std::max(1,cent.y-r),ry=std::min(n,cent.y+r);j<=ry;j++){ if((Point(i,j)-cent).sqr()<=r*r){ q.push(Point(i,j)); vis[i][j]=1; dis[i][j]=0; } } } while(!q.empty()){ Point cp=q.front();q.pop(); for(int i=0;i<8;i++){ Point np=cp+dir[i]; if(!vis[np.x][np.y]&&dat(np)&&(!(i&1)||dat(cp+dir[i-1])||dat(cp+dir[i+1]))){ vis[np.x][np.y]=1; dis[np.x][np.y]=dis[cp.x][cp.y]+1; q.push(np); } } } for(int i=1;i<=m;i++) hp[i]-=dis[pos[i].x][pos[i].y],pos[i].Read(); } inline void Solve(){ while(f--){ cent.Read();read(r); bfs(); } for(int i=1;i<=m;i++) printf("%d\n",hp[i]<0?0:hp[i]); } int main(){ freopen("battleground.in","r",stdin); freopen("battleground.out","w",stdout); Init(); Solve(); fclose(stdin);fclose(stdout); return 0; }