NOIP2020.9.19模拟 spongebob

题目大意

求解绝对值方程 \(|a_1x + b_1| + |a_2x+b_2| + ... + |a_nx+b_n|\) 的最小值

解题思路

方法一

先求零点值,考虑每一段的正负情况,可以用前缀和维护

方法二

\(Code\)

#include<cstdio>
#include<algorithm>
using namespace std;
double sx[300005],sz[300005];
int n;

struct nd{
	double x,b,k;
}a[300005];
bool cmp(nd x,nd y){return x.k < y.k;}
int main()
{
	scanf("%d",&n);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lf%lf",&a[i].x,&a[i].b);
		a[i].k = -a[i].b / a[i].x;
	}
	sort(a + 1,a + 1 + n,cmp);
	for (int i = 1; i <= n; i++)
		if (a[i].x < 0)
		sx[i] = sx[i - 1] - a[i].x,sz[i] = sz[i - 1] - a[i].b;
		else
		sx[i] = sx[i - 1] + a[i].x,sz[i] = sz[i - 1] + a[i].b;
	double ans = min(-sx[n] * a[1].k - sz[n],sx[n] * a[n].k + sz[n]);
	for (int i = 2; i <= n; i++)
	{
		double l = 2 * sx[i - 1] - sx[n];
		double r = 2 * sz[i - 1] - sz[n];
		if (l < 0) ans = min(ans,l * a[i].k + r);
		else ans = min(ans,l * a[i - 1].k + r);
	}
	printf("%.6lf\n",ans);
}
posted @ 2020-09-19 14:39  RiverSheep  阅读(102)  评论(0编辑  收藏  举报