题目大意
求解绝对值方程 (|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
",ans);
}