• 7250. 【USACO 2020 December Contest, Gold】Replication


    Description&&Data Constraint

    Solution

    首先我们可以求出每个点距离最近的岩石的距离,来判断能否走到这个点。

    同时因为机器人可以放置在任何一个起始位置,所以对于每个不是岩石或者起始点的点,可以求出它到最近的起始点的距离,来表示初始机器人走到那个点的时间。

    但走的时候要注意,只有能走到才能走。

    就是说如果到达这个点的时候,副本机器人撞到岩石了,那么这个点就不能继续往下扩展了。

    那么什么情况下是无法到达呢?

    现在我们已经知道了当前点距离最近的起点的距离,那么就可以算出产生出来的副本距离当前点的曼哈顿距离,也就是 (lfloor dfrac{dis_{x,y}}{d} floor)

    用这个去跟当前距离最近岩石的距离比较一下,如果大于等于距离最近岩石的距离,就说明副本机器人撞岩石了,就不用从这个点继续扩展了。

    上面的两个都可以用 ( ext{bfs}) 来处理。

    那么现在对于初始机器人可以直接走到的位置都已经处理出来了(即 (dis_{i,j}ge 0) 的位置),我们离解决这题只剩下求出副本机器人到的位置数量。

    注:首先避免重复,可以把算过的位置打上标记。

    这里我们考虑将 ( ext{bfs}) 的方式调转一下,对于初始机器人能到达的位置,从这个位置往外扩展来走到副本机器人能走到的位置。

    而这个向外走的距离,要么是到达此点时复制机器人的次数,或者是到最近的岩石距离减去 1,代表着岩石与当前位置之间的空位。

    但此时的队列并不一定满足单调,所以要将队列转成优先队列来模拟大根堆。

    Code

    #include<queue>
    #include<cstdio>
    #include<cstring>
    #define N 1005
    using namespace std;
    struct node
    {
    	int x,y,dis;
    };
    struct node1
    {
    	int x,y,dis;
    	friend bool operator <(const node1 &X,const node1 &Y) {return X.dis<Y.dis;}
    };
    queue<node> q_rock,q_robot;
    priority_queue<node1> getans;
    int n,d,ans,fx[5]={0,1,-1,0,0},fy[5]={0,0,0,1,-1},a[N][N],torock[N][N],frorobot[N][N];
    bool bj[N][N];
    char s[N];
    int main()
    {
    	memset(torock,-1,sizeof(torock));
    	memset(frorobot,-1,sizeof(frorobot));
    	scanf("%d%d",&n,&d);
    	for (int i=1;i<=n;++i)
    	{
    		scanf("%s",s+1);
    		for (int j=1;j<=n;++j)
    		{
    			if (s[j]=='#')
    			{
    				a[i][j]=1;
    				node x;
    				x.x=i;x.y=j;x.dis=0;
    				q_rock.push(x);
    				torock[i][j]=0;
    			}
    			if (s[j]=='S')
    			{
    				a[i][j]=1;
    				node x;
    				x.x=i;x.y=j;x.dis=0;
    				q_robot.push(x);
    				frorobot[i][j]=0;
    			}
    		}
    	}
    	while (!q_rock.empty())
    	{
    		node u=q_rock.front();q_rock.pop();
    		for (int i=1;i<=4;++i)
    		{
    			int xx=u.x+fx[i],yy=u.y+fy[i];
    			if (torock[xx][yy]<0&&xx>=1&&yy>=1&&xx<=n&&yy<=n)
    			{
    				torock[xx][yy]=u.dis+1;
    				node x;
    				x.x=xx;x.y=yy;x.dis=u.dis+1;
    				q_rock.push(x);
    			}
    		}
    	}
    	while (!q_robot.empty())
    	{
    		node u=q_robot.front();q_robot.pop();
    		if (u.dis/d>=torock[u.x][u.y]) continue;
    		for (int i=1;i<=4;++i)
    		{
    			int xx=u.x+fx[i],yy=u.y+fy[i];
    			if (frorobot[xx][yy]<0&&u.dis/d<torock[xx][yy]&&!a[xx][yy])
    			{
    				frorobot[xx][yy]=u.dis+1;
    				node x;
    				x.x=xx;x.y=yy;x.dis=u.dis+1;
    				q_robot.push(x);
    			}
    		}
    	}
    	for (int i=1;i<=n;++i)
    		for (int j=1;j<=n;++j)
    			if (frorobot[i][j]>=0)
    			{
    				node1 x;
    				x.x=i;x.y=j;x.dis=min(frorobot[i][j]/d,torock[i][j]-1);
    				getans.push(x);
    				bj[i][j]=true;
    				++ans;
    			}
    	while (!getans.empty())
    	{
    		node1 u=getans.top();getans.pop();
    		if (!u.dis) continue;
    		for (int i=1;i<=4;++i)
    		{
    			int xx=u.x+fx[i],yy=u.y+fy[i];
    			if (!bj[xx][yy]&&!a[xx][yy])
    			{
    				bj[xx][yy]=true;
    				node1 x;
    				x.x=xx;x.y=yy;x.dis=u.dis-1;
    				getans.push(x);
    				++ans;
    			}
    		}
    	}
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    BZOJ2752: [HAOI2012]高速公路(road)
    BZOJ1146: [CTSC2008]网络管理Network
    BZOJ3545: [ONTAK2010]Peaks
    启发式算法
    特征选择算法
    傅里叶变换 小波变换
    流类库 输入输出
    模板与异常处理
    多态性
    派生类与继承
  • 原文地址:https://www.cnblogs.com/Livingston/p/15167015.html
Copyright © 2020-2023  润新知