ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF685C Optimal Point

2020-11-20 22:33:32  阅读:211  来源: 互联网

标签:return hl Point ll CF685C HL Optimal false jg


题意:给定一个立体直角坐标系上的\(n\)个整点,求一个整点满足到这\(n\)个整点的曼哈顿距离的最大值最小。
首先显然二分。
那么,要解若干方程:|x-Xi|+|y-Yi|+|z-Zi|<=m。
遇到绝对值方程/不等式,我们有2种方式:

  1. 零点分段
  2. 拆方程:|a|拆成a,-a。
    考虑第二种方法。
    会得到8个不等式。把x系数都调为1,剩余4个不等式。
    由于是4个不等式,3个变量,因此一定有一个式子能被其它式子表出。
    把其他式子换元为abc,那么我们可以知道abc的范围,以及a+b+c的范围。
    同时,由于要求整点,还要满足abc奇偶性相同。
    枚举除以2的余数,进行计算即可。
    细节很多。
    代码:
#include <stdio.h>
#define ll long long
#define inf 9e18
ll mabs(ll s)
{
    return s>=0?s:-s;
}
bool solve(ll L[3],ll R[3],ll HL,ll HR,ll A[3])
{
    if(HL>HR)return false;
    ll hl=0,hr=0;
    for(int i=0;i<3;i++)
    {
        if(L[i]>R[i])return false;
        hl+=L[i],hr+=R[i],A[i]=L[i];
    }
    if(hl>HR||HL>hr)
        return false;
    if(hl>=HL)
        return true;
    ll sy=HL-hl;
    for(int i=0;i<3;i++)
    {
        ll z=R[i]-L[i];
        if(sy<z)z=sy;
        A[i]+=z;sy-=z;
    }
    return true;
}
void div2(ll &L,ll &R)
{
    ll l=L/2,r=R/2;
    if(r*2>R)r-=1;
    if(l*2<L)l+=1;
    L=l;R=r;
}
ll X[100010],Y[100010],Z[100010],S[2][2][2],L[2][2],R[2][2];int n;
bool check(ll m,ll A[3])
{
    for(int a=0;a<2;a++)
        for(int b=0;b<2;b++)
            for(int c=0;c<2;c++)
                S[a][b][c]=inf;
    for(int i=1;i<=n;i++)
    {
        for(int a=0;a<2;a++)
        {
            for(int b=0;b<2;b++)
            {
                for(int c=0;c<2;c++)
                {
                    ll t=m+X[i]*(a*2-1)+Y[i]*(b*2-1)+Z[i]*(c*2-1);
                    if(t<S[a][b][c])S[a][b][c]=t;
                }
            }
        }
    }
    for(int a=0;a<2;a++)
    {
        for(int b=0;b<2;b++)
        {
            L[a][b]=-S[0][a^1][b^1],R[a][b]=S[1][a][b];
            if(L[a][b]>R[a][b])return false;
        }
    }
    ll l[3]={-R[1][1],L[1][0],L[0][1]},r[3]={-L[1][1],R[1][0],R[0][1]};
    for(int k=0;k<2;k++)
    {
        ll zl[3],zr[3],hl=L[0][0]-k*3,hr=R[0][0]-k*3;
        for(int i=0;i<3;i++)
        {
            zl[i]=l[i]-k;zr[i]=r[i]-k;
            div2(zl[i],zr[i]);
        }
        div2(hl,hr);ll jg[3];
        if(solve(zl,zr,hl,hr,jg))
        {
            ll a=jg[0]*2+k,b=jg[1]*2+k,c=jg[2]*2+k;
            A[0]=(b+c)/2;A[1]=(-a-c)/2;A[2]=(-a-b)/2;
            return true;
        }
    }
    return false;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ll l=0,r=0,jg[3];
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            scanf("%lld%lld%lld",&X[i],&Y[i],&Z[i]);
            ll t=mabs(X[i])+mabs(Y[i])+mabs(Z[i]);
            if(t>r)r=t;
        }
        while(l<r)
        {
            ll m=(l+r)>>1;
            if(check(m,jg))
                r=m;
            else
                l=m+1;
        }
        check(l,jg);
        printf("%lld %lld %lld\n",jg[0],jg[1],jg[2]);
    }
    return 0;
}

标签:return,hl,Point,ll,CF685C,HL,Optimal,false,jg
来源: https://www.cnblogs.com/lnzwz/p/14013351.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有