• “知乎杯”2018 CCF 大学生计算机系统与程序设计竞赛 绝地求生(battleground)


    CSPfinal 2018

     

    绝地求生

            对于第1个子任务,由于所有玩家都在安全区内,直接输出玩家初始生命值即可;

            对于第2个和第4个子任务,由于数据量较小,可以从玩家开始向安全区做路径搜索;

            对于第3个和第5个子任务,由于数据量较大,可以从安全区做一次路径搜索;

            每回合开始清除安全区内的障碍物,每回合结束恢复安全区内的障碍物;

            玩家不能进入障碍物的方格;

           if(abstacles[xnew][ynew]==1) return;

            也不能穿越两个斜向相邻障碍物方格的间隙;

           if(abstacles[xold][ynew]&&abstacles[xnew][yold]==1) return;

     

    把所有安全区的点放入队列,bfs,得到初始点到安全区的最短距离。

    题目保证每个玩家给出的目标坐标一定在安全区域以内。保证在任意回合,对于任意玩家,都存在一条到达本回合目标位置的移动路线

    所以本次的最短距离即为本轮该玩家的扣血量。

     

    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
    ",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;
    }

     

  • 相关阅读:
    Android内存管理篇
    Android内存管理篇
    Java:ServiceLoader未加载服务提供实现类
    Java:SPI机制
    利用向量积(叉积)计算三角形的面积和多边形的面积
    VMware虚拟机安装WinXP出现错误output error file to the following location A:GHOSTERR.TXT
    @media与css先后顺序产生的优先级问题
    css 始终显示滚动条,内容超出显示有滑块的滚动条,内容没有超出显示空的滚动条
    css 内容溢出显示垂直滚动条,内容不超出就不显示滚动条
    css 一行或多行文字溢出以...的形式隐藏
  • 原文地址:https://www.cnblogs.com/shenben/p/11614869.html
Copyright © 2020-2023  润新知