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;
    }
    
  • 相关阅读:
    Numpy 里线性代数函数
    lateral view 使用方法
    Numpy 基础函数
    Numpy 基础操作
    pandas 基础操作记录学习
    pandas向左移动非空单元格
    供应商自动记账
    SAP Smartforms 参数配置
    SAP FPM 相关包 APB_FPM_CORE
    SAP BPC 清除CUBE 中的数据
  • 原文地址:https://www.cnblogs.com/stoorz/p/13827628.html
Copyright © 2011-2022 走看看