CodeChef:Travel to all Points(二分 & 技巧)


思路:二分答案,O(n)验证,|p-x|+|q-y| >= d可互达,相当于

(P+Q)-(X+Y)>=D
(P+Q)-(X+Y)<=-D
(P-Q)-(X-Y)>=D
(P-Q)-(X-Y)<=-D

任一种情况都可互达,那么设置两个数组分别对x+y和x-y排序,BFS看是否能够到达所有点即可,参考作者题解。

# include <bits/stdc++.h>
# define mp make_pair
using namespace std;
typedef long long LL;
const int maxn = 1e6+30;
const int INF = 2e9+10;
int n, x1[maxn], x2[maxn], vis[maxn], q[maxn<<1];
pair<int,int>x3[maxn], x4[maxn];

bool check(int d)
{
    memset(vis, 0, sizeof(vis));
    int l=0, r=0, x3_h=0, x3_t=n-2, x4_h=0, x4_t=n-2;
    q[r++] = 0;
    vis[0] = 1;
    auto add = [&](int v)
    {
        q[r++] = v;
        vis[v] = 1;
        while(x3_h <= x3_t && vis[x3[x3_t].second]) --x3_t;
        while(x3_h <= x3_t && vis[x3[x3_h].second]) ++x3_h;
        while(x4_h <= x4_t && vis[x4[x4_h].second]) ++x4_h;
        while(x4_h <= x4_t && vis[x4[x4_t].second]) --x4_t;
    };
    while(l < r)
    {
        int u = q[l++];
        while(x3_h <= x3_t && x1[u] - x3[x3_t].first <= -d) add(x3[x3_t].second);
        while(x3_h <= x3_t && x1[u] - x3[x3_h].first >= d) add(x3[x3_h].second);
        while(x4_h <= x4_t && x2[u] - x4[x4_h].first >= d) add(x4[x4_h].second);
        while(x4_h <= x4_t && x2[u] - x4[x4_t].first <= -d) add(x4[x4_t].second);

    }
    return l == n;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        for(int a, b, i=0; i<n; ++i)
        {
            scanf("%d%d",&a,&b);
            x1[i] = a+b;
            x2[i] = a-b;
            if(i)
            {
                x3[i-1] = mp(x1[i], i);
                x4[i-1] = mp(x2[i], i);
            }
        }
        sort(x3, x3+n-1);
        sort(x4, x4+n-1);
        int l=0, r=INF;
        while(l <= r)
        {
            int m = (LL)l+r>>1;
            if(check(m)) l = m+1;
            else r = m-1;
        }
        printf("%d\n",r);
    }
    return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值