結果
問題 | No.180 美しいWhitespace (2) |
ユーザー |
![]() |
提出日時 | 2016-01-27 00:59:24 |
言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 2,454 bytes |
コンパイル時間 | 1,380 ms |
コンパイル使用メモリ | 165,196 KB |
実行使用メモリ | 6,948 KB |
最終ジャッジ日時 | 2024-09-21 17:38:42 |
合計ジャッジ時間 | 2,808 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge2 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 4 |
other | AC * 21 WA * 10 |
ソースコード
#include <bits/stdc++.h> typedef long long ll; typedef unsigned long long ull; #define FOR(i,a,b) for(int (i)=(a);i<(b);i++) #define REP(i,n) FOR(i,0,n) #define RANGE(vec) (vec).begin(),(vec).end() using namespace std; class BeautifulWhitespace2 { public: void solve(void) { int N; cin>>N; vector<ll> a(N); vector<ll> b(N); REP(i,N) cin>>a[i]>>b[i]; // // // / | // --- / | // --- / | // // のような傾きの異なる 3 直線とすると // max(a[i]+b[i]*x) は領域 A 側にもっとも近い線分 // min(a[i]+b[i]*x) は領域 B 側にもっとも近い線分 // // |/ // A / // /| // /|------- // ----/- // / | B // // によって構成される。また max(...) => min(...) なので // 差は必ず 0 以上となる。よって f(x) は極値を 1 つもつ凹関数となる。 // 三分探索をすればよい。 const double inf = (1<<30); // O(N) auto f = [=](double x) { if (x <= 0) return inf; double maxF = a[0]+b[0]*x; double minF = a[0]+b[0]*x; FOR(i,1,N) { minF = min(minF, a[i]+b[i]*x); maxF = max(maxF, a[i]+b[i]*x); } return maxF - minF; }; const int maxLoop = 1000; double left = 1; double right = (1<<30); // O(N*1000) for (int loop = 0; loop < maxLoop; ++loop) { if ( fabs(left - right) < 1e-3 ) break; // // l ---u---v--- r // double u = (left*2 + right)/3; double v = (left + right*2)/3; if ( f(u) > f(v) ) left = u; else right = v; } ll x = (left+right)*0.5; // 前後 1 つ分くらいは調べてみる auto xs = vector<ll> {x-1, x, x+1}; cout<<*min_element(RANGE(xs), [=](ll a, ll b) { return f(a)<f(b);})<<endl; } }; #if 1 int main(int argc, char *argv[]) { ios::sync_with_stdio(false); auto obj = new BeautifulWhitespace2(); obj->solve(); delete obj; return 0; } #endif