题意:
给出n个点对,定义每两个点之间的价值为m i n ( x i − x j , y i − y j ),求最大价值。
思路:
实际上就是要最小值最大化,答案明显是有单调性的,考虑是否能够二分答案来做。
假设当前枚举到m i d,合法的条件就是m i n ( x i − x j , y i − y j ) > = m i d,也就是说x i − x j > = m i d 并且y i − y j > = m i d。
在c h e c k的时候,可以枚举其中一个点( x , y ),看是否存在( xi y i )满足x − x i > = m i d 且y − y i > = m i d.
先对所有的点按照x从小到大排序,对于x前面的点来说,就可以用队列维护出x − x i > = m i d的点。再判断这些点里有没有y − y i > = m i d 的就可以了。维护一个y的最大值m a x x和最小值m i n n ,如果y − m i n n > = m i d或m a x x − y > = m i d ,说明当前m i d合法,可以使得值更大,左指针右移。
整体时间复杂度O ( n l o g n )
代码:
// Problem: F - Dist Max 2 // Contest: AtCoder - AtCoder Beginner Contest 215 // URL: https://atcoder.jp/contests/abc215/tasks/abc215_f // Memory Limit: 1024 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) #pragma GCC optimize(1) #pragma GCC optimize(2) #pragma GCC optimize(3,"Ofast","inline") #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll, ll>PLL; typedef pair<int, int>PII; typedef pair<double, double>PDD; #define I_int ll inline ll read(){ll x = 0, f = 1;char ch = getchar();while(ch < '0' || ch > '9'){if(ch == '-')f = -1;ch = getchar();}while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}return x * f;} inline void write(ll x){if (x < 0) x = ~x + 1, putchar('-');if (x > 9) write(x / 10);putchar(x % 10 + '0');} #define read read() #define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0) #define multiCase int T;cin>>T;for(int t=1;t<=T;t++) #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i<(b);i++) #define per(i,a,b) for(int i=(a);i>=(b);i--) #define perr(i,a,b) for(int i=(a);i>(b);i--) ll ksm(ll a, ll b,ll mod){ll res = 1;while(b){if(b&1)res=res*a%mod;a=a*a%mod;b>>=1;}return res;} const int maxn=1e6+7; struct node{ int x,y; }; bool cmp(node a,node b){ return a.x<b.x; } vector<node>g; int n; bool check(int mid){ queue<node>q; int minn = 1e9, maxx = 0,flag=0; for(node t:g){ while(!q.empty()){ if(t.x-q.front().x<mid) break; minn=min(minn,q.front().y); maxx=max(maxx,q.front().y); q.pop(); } if(t.y-minn>=mid||maxx-t.y>=mid) flag=1; q.push(t); } return flag; } int main(){ n=read; rep(i,1,n){ int x=read,y=read; g.push_back({x,y}); } sort(g.begin(),g.end(),cmp); int l=0,r=1e9,res=0; while(l<=r){ int mid=(l+r)/2; if(check(mid)) l=mid+1,res=mid; else r=mid-1; } cout<<res<<endl; return 0; }