zoukankan      html  css  js  c++  java
  • Electric Charges CodeForces

    大意: 平面上n个点每个点坐标为(x,0)或(0,y), 求任意两点距离平方最大值的最小值.

    二分答案, 转化为判定最大值是否<=e, 按$x$排序后, 因为固定左端点, $y$绝对值的最大值是跟右端点单调的, 滑动一个长度平方不超过e的区间, 同时保证右端点$x$的绝对值不超过左端点, 这样对于左端点在$x$轴的情况一定是最优的, 同样再固定右端点倒序处理正半轴的情况.

    #include <iostream>
    #include <random>
    #include <algorithm>
    #include <cstdio>
    #include <math.h>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <string.h>
    #include <bitset>
    #define REP(i,a,n) for(int i=a;i<=n;++i)
    #define PER(i,a,n) for(int i=n;i>=a;--i)
    #define hr putchar(10)
    #define pb push_back
    #define lc (o<<1)
    #define rc (lc|1)
    #define mid ((l+r)>>1)
    #define ls lc,l,mid
    #define rs rc,mid+1,r
    #define x first
    #define y second
    #define io std::ios::sync_with_stdio(false)
    #define endl '
    '
    #define DB(a) ({REP(__i,1,n) cout<<a[__i]<<' ';hr;})
    using namespace std;
    typedef long long ll;
    typedef pair<int,int> pii;
    const int P = 1e9+7, INF = 0x3f3f3f3f;
    ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
    ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
    ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
    inline int rd() {int x=0;char p=getchar();while(p<'0'||p>'9')p=getchar();while(p>='0'&&p<='9')x=x*10+p-'0',p=getchar();return x;}
    //head
    
    
    
    #ifdef ONLINE_JUDGE
    const int N = 1e6+10;
    #else
    const int N = 111;
    #endif
    
    int n;
    pii a[N];
    int Lmin[N], Lmax[N], Rmin[N], Rmax[N];
    
    ll sqr(ll x) {return x*x;}
    ll ans = 1e18;
    int chk(ll e) {
        if (ans<=e) return 1;
    	int now = 1;
    	ll ans = 1e18;
    	REP(i,1,n) {
    		if (a[i].x>0) break;
    		while (now<n&&sqr(a[now+1].x-a[i].x)<=e&&abs(a[now+1].x)<=abs(a[i].x)) ++now;
    		while (abs(a[now].x)>abs(a[i].x)) --now;
    		int U = -1e9, D = 1e9;
    		if (i>1) U=max(U,Lmax[i-1]),D=min(D,Lmin[i-1]);
    		if (now<n) U=max(U,Rmax[now+1]),D=min(D,Rmin[now+1]);
    		ans = min(ans, max(sqr(U-D),max(sqr(U),sqr(D))+max(sqr(a[i].x),sqr(a[now].x))));
    	}
    	now = n;
    	PER(i,1,n) {
    		if (a[i].x<0) break;
    		while (now>1&&sqr(a[now-1].x-a[i].x)<=e&&abs(a[now-1].x)<=abs(a[i].x)) --now;
    		while (abs(a[now].x)>abs(a[i].x)) ++now;
    		int U = -1e9, D = 1e9;
    		if (i<n) U=max(U,Rmax[i+1]),D=min(D,Rmin[i+1]);
    		if (now>1) U=max(U,Lmax[now-1]),D=min(D,Lmin[now-1]);
    		ans = min(ans, max(sqr(U-D),max(sqr(U),sqr(D))+max(sqr(a[i].x),sqr(a[now].x))));
    	}
    	return ans<=e;
    }
    
    int main() {
    	scanf("%d", &n);
    	REP(i,1,n) scanf("%d%d", &a[i].x,&a[i].y);
    	sort(a+1,a+1+n);
    	Lmin[1]=Lmax[1]=a[1].y;
    	REP(i,2,n) { 
    		Lmin[i]=min(Lmin[i-1],a[i].y);
    		Lmax[i]=max(Lmax[i-1],a[i].y);
    	}
    	Rmin[n]=Rmax[n]=a[n].y;
    	PER(i,1,n-1) {
    		Rmin[i]=min(Rmin[i+1],a[i].y);
    		Rmax[i]=max(Rmax[i+1],a[i].y);
    	}
    	ll l = 0, r = min(sqr(Lmin[n]-Lmax[n]),sqr(a[1].x-a[n].x));
    	ans = r;
    	while (l<=r) {
    		if (chk(mid)) ans=mid,r=mid-1;
    		else l=mid+1;
    	}
    	printf("%lld
    ", ans);
    }
    
  • 相关阅读:
    LeetCode 811. Subdomain Visit Count (子域名访问计数)
    LeetCode 884. Uncommon Words from Two Sentences (两句话中的不常见单词)
    LeetCode 939. Minimum Area Rectangle (最小面积矩形)
    LeetCode 781. Rabbits in Forest (森林中的兔子)
    LeetCode 739. Daily Temperatures (每日温度)
    三种方式实现按钮的点击事件
    239. Sliding Window Maximum
    14.TCP的坚持定时器和保活定时器
    13.TCP的超时与重传
    12.TCP的成块数据流
  • 原文地址:https://www.cnblogs.com/uid001/p/10798588.html
Copyright © 2011-2022 走看看