zoukankan      html  css  js  c++  java
  • 【GMOJ6800】模拟spongebob

    题目

    题目链接:https://gmoj.net/senior/#main/show/6800
    给出 (n) 和两个长度为 (n) 的数组 (a,b),求

    [min{sum^{n}_{i=1}|a_ix+b_i|} ]

    其中 (xin mathbb{R})

    思路

    先把 (a=0) 的所有直线的 (|b|) 加到答案里。
    对于剩余的直线,我们按照他们与 (x) 轴交点排序,依次枚举交点区间并计算出此时最优的 (x),判断 (x) 与当前区间位置分别计算答案即可。
    时间复杂度 (O(nlog n))

    代码

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    const int N=300010;
    int n,m;
    ll sum,suma,sumb;
    double ans;
    
    struct node
    {
    	ll a,b;
    	double p;
    }a[N];
    
    bool cmp(node x,node y)
    {
    	if (x.a==0) return 0;
    	if (y.a==0) return 1;
    	return x.p<y.p;
    }
    
    int main()
    {
    	freopen("spongebob.in","r",stdin);
    	freopen("spongebob.out","w",stdout);
    	scanf("%d",&m); n=m;
    	for (int i=1;i<=m;i++)
    	{
    		scanf("%lld%lld",&a[i].a,&a[i].b);
    		if (a[i].a!=0) a[i].p=-1.0*a[i].b/a[i].a;
    			else sum+=abs(a[i].b),n--;
    	}
    	sort(a+1,a+1+m,cmp);
    	for (int i=1;i<=n;i++)
    		if (a[i].a>0) suma-=a[i].a,sumb-=a[i].b;
    			else suma+=a[i].a,sumb+=a[i].b;
    	a[0].p=-10000000000000000.0; a[n+1].p=10000000000000000.0;
    	ans=10000000000000000.0;
    	for (int i=1;i<=n+1;i++)
    	{
    		double l=a[i-1].p,r=a[i].p,x=-1.0*sumb/suma;
    		if (l<=x && x<=r) ans=0;
    		if (x<l) ans=min(ans,suma*l+sumb);
    		if (x>r) ans=min(ans,suma*r+sumb);
    		if (a[i].a>0) suma+=2LL*a[i].a,sumb+=2LL*a[i].b;
    			else suma-=2LL*a[i].a,sumb-=2LL*a[i].b;
    	}
    	printf("%.8lf",ans+sum);
    	return 0;
    }
    
  • 相关阅读:
    asp.net微信开发第八篇----永久素材管理
    selenium模块
    request模块
    爬虫基本概念
    反向生成url
    admin的路由系统剖析
    popup方法
    ModelForm
    Django数据库操作性能相关
    缓存
  • 原文地址:https://www.cnblogs.com/stoorz/p/13827628.html
Copyright © 2011-2022 走看看