• Simpson公式的应用(HDU 1724/ HDU 1071)


    辛普森积分法 - 维基百科,自由的百科全书

    Simpson's rule - Wikipedia, the free encyclopedia

      利用这个公式,用二分的方法来计算积分。

    1071 ( The area )

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cmath>
     6 
     7 using namespace std;
     8 
     9 const double EPS = 1e-8;
    10 double A, B, C, P, Q;
    11 
    12 template<class T> T sqr(T x) { return x * x;}
    13 inline double cal(double x) { return A * sqr(x) + (B - P) * x + C - Q;}
    14 inline double sps(double l, double r) { return (cal(l) + cal(r) + 4 * cal((l + r) / 2)) / 6 * (r - l);}
    15 
    16 double work(double l, double r) {
    17     //cout << l << ' ' << r << endl;
    18     double ans = sps(l, r), m = (l + r) / 2;
    19     if (fabs(ans - sps(l, m) - sps(m, r)) < EPS) return ans;
    20     else return work(l, m) + work(m, r);
    21 }
    22 
    23 
    24 int main() {
    25     int T;
    26     double l, r;
    27     double x[3], y[3];
    28     cin >> T;
    29     while (T--) {
    30         for (int i = 0; i < 3; i++) cin >> x[i] >> y[i];
    31         double p[2], q[2], d[2];
    32         for (int i = 0; i < 2; i++) p[i] = sqr(x[i]) - sqr(x[i + 1]), q[i] = x[i] - x[i + 1], d[i] = y[i] - y[i + 1];
    33         A = (q[1] * d[0] - q[0] * d[1]) / (p[0] * q[1] - p[1] * q[0]);
    34         B = (p[1] * d[0] - p[0] * d[1]) / (p[1] * q[0] - p[0] * q[1]);
    35         C = y[0] - B * x[0] - A * sqr(x[0]);
    36         //cout << A << ' ' << B << ' ' << C << endl;
    37         P = (y[1] - y[2]) / (x[1] - x[2]);
    38         Q = y[1] - P * x[1];
    39         //cout << P << ' ' << Q << endl;
    40         printf("%.2f
    ", work(x[1], x[2]));
    41     }
    42     return 0;
    43 }
    View Code

    1724 ( Ellipse )

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cmath>
     6 
     7 using namespace std;
     8 
     9 const double EPS = 1e-8;
    10 double A, B;
    11 
    12 template<class T> T sqr(T x) { return x * x;}
    13 inline double cal(double x) { return 2 * B * sqrt(1 - sqr(x) / sqr(A));}
    14 inline double sps(double l, double r) { return (cal(l) + cal(r) + 4 * cal((l + r) / 2)) / 6 * (r - l);}
    15 
    16 double work(double l, double r) {
    17     //cout << l << ' ' << r << endl;
    18     double ans = sps(l, r), m = (l + r) / 2;
    19     if (fabs(ans - sps(l, m) - sps(m, r)) < EPS) return ans;
    20     else return work(l, m) + work(m, r);
    21 }
    22 
    23 int main() {
    24     int T;
    25     double l, r;
    26     cin >> T;
    27     while (T-- && cin >> A >> B >> l >> r) printf("%.3f
    ", work(l, r));
    28     return 0;
    29 }
    View Code

      之后还有题会继续更新。

    UPD:

      就是因为见过这题,所以才学这个公式的。1y~

     ACM-ICPC Live Archive

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <cmath>
     6 
     7 using namespace std;
     8 
     9 double coe[4][11];
    10 const double EPS = 1e-8;
    11 
    12 int k;
    13 double cal(double x, double *c) {
    14     double ret = c[0];
    15     for (int i = 1; i <= k; i++) ret *= x, ret += c[i];
    16     return ret;
    17 }
    18 
    19 inline double cal(double x, double *p, double *q) { return cal(x, p) / cal(x, q);}
    20 inline double cal(double x, double y, double *p, double *q) { return max(cal(x, p, q) - y, 0.0);}
    21 inline double simpson(double y, double l, double r, double *p, double *q) { return (cal(l, y, p, q) + cal(r, y, p, q) + 4 * cal((l + r) / 2, y, p, q)) * (r - l) / 6;}
    22 
    23 inline double getpart(double y, double l, double r, double *p, double *q) {
    24     double sum = simpson(y, l, r, p, q);
    25     //cout << l << ' ' << r << ' ' << sum << endl;
    26     if (fabs(sum - simpson(y, l, (l + r) / 2, p, q) - simpson(y, (l + r) / 2, r, p, q)) < EPS) return sum;
    27     return getpart(y, l, (l + r) / 2, p, q) + getpart(y, (l + r) / 2, r, p, q);
    28 }
    29 
    30 inline double getarea(double y, double l, double r, double *p, double *q) {
    31     double ret = 0, d = (r - l) / 100;
    32     for (int i = 0; i < 100; i++) {
    33         ret += getpart(y, l + d * i, l + d * (i + 1), p, q);
    34     }
    35     return ret;
    36 }
    37 
    38 double dc2(double l, double r, double a, double w) {
    39     double m;
    40     while (r - l > EPS) {
    41         m = (l + r) / 2.0;
    42         //cout << m << ' ' << getarea(m, 0, w, coe[0], coe[1]) - getarea(m, 0, w, coe[2], coe[3]) << endl;
    43         if (getarea(m, 0, w, coe[0], coe[1]) - getarea(m, 0, w, coe[2], coe[3]) > a) l = m;
    44         else r = m;
    45     }
    46     return l;
    47 }
    48 
    49 int main() {
    50     //freopen("in", "r", stdin);
    51     //freopen("out", "w", stdout);
    52     double w, d, a;
    53     while (cin >> w >> d >> a >> k) {
    54         for (int i = 0; i < 4; i++) for (int j = 0; j <= k; j++) cin >> coe[i][j];
    55         for (int i = 0; i < 4; i++) reverse(coe[i], coe[i] + k + 1);
    56         //cout << getarea(-5.51389, 0, w, coe[0], coe[1]) - getarea(-5.51389, 0, w, coe[2], coe[3]) << endl;
    57         //cout << cal(3, coe[0], coe[1]) << endl;
    58         printf("%.5f
    ", -dc2(-d, 0, a, w));
    59     }
    60     return 0;
    61 }
    View Code

    ——written by Lyon

  • 相关阅读:
    二维线性表 list实现
    行测题
    邻接表
    链表中插入和删除结点
    linux监控指标和命令
    lr测试结果分析
    python 装饰器 decorator
    并查集 PID331 / 家族
    素数环 dfs+回溯
    catch the cow bfs
  • 原文地址:https://www.cnblogs.com/LyonLys/p/simpson_Lyon.html
Copyright © 2020-2023  润新知