結果

問題 No.2438 Double Least Square
ユーザー hiromi_ayase
提出日時 2025-02-22 15:56:58
言語 C++23
(gcc 13.3.0 + boost 1.87.0)
結果
WA  
実行時間 -
コード長 2,219 bytes
コンパイル時間 6,794 ms
コンパイル使用メモリ 334,116 KB
実行使用メモリ 6,820 KB
最終ジャッジ日時 2025-02-22 15:57:10
合計ジャッジ時間 11,612 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 3
other AC * 25 WA * 5
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>

#include <atcoder/all>
using namespace std;
using i32 = int;
using u32 = unsigned int;
using i64 = long long;
using u64 = unsigned long long;
#define FAST_IO                \
  ios::sync_with_stdio(false); \
  cin.tie(0);
const i64 INF = 1001001001001001001;
using Modint = atcoder::static_modint<998244353>;

int N;
double H;
vector<double> x, y;

double L(double a1, double a2) {
  double ret = 0;
  for (int i = 0; i < N; i++) {
    double y1 = a1 * x[i] + H/2;
    double y2 = a2 * x[i] - H/2;
    ret += min(pow(y1 - y[i], 2), pow(y2 - y[i], 2));
  }
  return ret;
}

pair<double, double> ternary_search(double mn, double mx, function<double(double)> f, int iter) {
  double l = mn, r = mx;
  for (int i = 0; i < iter; i++) {
    double theta1 = (l * 2 + r) / 3;
    double theta2 = (l + r * 2) / 3;
    if (f(theta1) < f(theta2)) {
      r = theta2;
    } else {
      l = theta1;
    }
  }
  return {l, f(l)};
}

tuple<double, double, double> search(double min_alpha, double max_alpha) {

  int iter = 100;

  auto ans = ternary_search(min_alpha, max_alpha, [&](double alpha) {
    double max_beta = min(M_PI / 2 - alpha, alpha + M_PI / 2);
    double min_beta = -max_beta;

    auto v = ternary_search(min_beta, max_beta, [&](double beta) {
      return L(tan(alpha + beta), tan(alpha - beta));
    }, iter);

    return v.second;
  }, iter);

  auto alpha = ans.first;
  double max_beta = min(M_PI / 2 - alpha, alpha + M_PI / 2);
  double min_beta = -max_beta;

  auto v = ternary_search(
      min_beta, max_beta,
      [&](double beta) { return L(tan(alpha + beta), tan(alpha - beta)); },
      iter);
  auto beta = v.first;

  return {alpha, beta, v.second};
}



int main() {
  FAST_IO

  cin >> N >> H;
  x.resize(N);
  y.resize(N);
  for (int i = 0; i < N; i++) {
    cin >> x[i] >> y[i];
  }

  for (int i = 0; i < N; i++) {
    y[i] -= H / 2;
  }

  double max_alpha = -M_PI / 2;
  double min_alpha = M_PI / 2;
  for (int i = 0; i < N; i++) {
    double alpha = atan2(y[i], x[i]);
    max_alpha = max(max_alpha, alpha);
    min_alpha = min(min_alpha, alpha);
  }

  auto [alpha, beta, ans] = search(min_alpha, max_alpha);
  cout << fixed << setprecision(10) << ans << endl;
}
0