NOIP2020.9.19模擬 spongebob
阿新 • • 發佈:2020-09-19
題目大意
求解絕對值方程 \(|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); }