Skip to content
Runtime
Go back

平面直角坐标系的斜线移动

Edit page

总结

对于斜线移动的情况,即位置为 (x,y)(x, y) 的点可以跳跃到 (x+1,y+1)(x+1, y+1)(x+1,y1)(x+1, y-1)(x1,y+1)(x-1, y+1)(x1,y1)(x-1, y-1)

为方便处理,我们旋转平面直角坐标系45°,同时以旋转后的22\frac{\sqrt2}{2}格对标旋转前的11

若旋转前坐标为(X,Y)(X,Y),那么旋转后坐标(x,y)=(X+Y,XY)(x,y)=(X+Y,X-Y)

可以发现旋转后的距离问题变成了曼哈顿距离:若两点的xx的奇偶性相同则可以相互到达,dist(A,B)=12(x1x2+y1y2)\text{dist}(A,B)=\frac{1}{2}(\lvert x_1-x_2\rvert+\lvert y_1-y_2\rvert),否则无法到达

E - Jump Distance Sum

地址

求解i=1N1j=i+1Ndist(Pi,Pj)\displaystyle\sum_{i=1}^{N-1}\displaystyle\sum_{j=i+1}^N \text{dist}(P_i, P_j),直接做会存在绝对值的问题

正确的做法是先根据x,yx,y与它们的奇偶性分为四组,对于每一组升序排序后求贡献

void SINGLE_TEST()
{
    int n;cin>>n;
    vector<int> x(n+1),y(n+1);
    vector<vector<int>> g(4);
    for(int i=1;i<=n;i++){
        cin>>x[i]>>y[i];
        g[(x[i]+y[i])%2].push_back(x[i]+y[i]);
        g[2+(x[i]+y[i])%2].push_back(x[i]-y[i]);
    }

    for(int i=0;i<4;i++) sort(g[i].begin(),g[i].end());

    ll ans=0;
    for(int loc=0;loc<4;loc++){
        int siz=g[loc].size();
        for(int i=0;i<siz;i++){
            ans+=(i-(siz-i-1))*g[loc][i];
        }
    }
    cout<<ans/2<<'\n';
}

Edit page
Share this post on:

Previous Post
线段树
Next Post
字典树