[hdu4498]离散化,simpson求积分
阅读原文时间:2023年07月08日阅读:1

题意:,求这个函数在[0,100]上的图像的长度。

思路:采用离散化的思想,求出所有交点 ,把交点排序,把[0,100]分成若干个小区间,这样原函数在每个小区间上的图像属于某一个二次函数或者是一条直线。如何确定属于哪个呢?比如对于某个区间,令m为这个小区间的中点,求出所有的函数在m点的函数值的最小值,对应的那个函数就是答案。如果最小值>=100则说明是直线。那么问题就变成了求二次函数曲线在区间[L,R]上的长度。这个可以转化为积分来算,令f(x)为原函数的倒数,则答案就是sqrt(1+f(x)*f(x))在[L,R]上的积分了。求积分可以用自适应辛普森法。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

#include&nbsp;<iostream>

#include&nbsp;<cstdio>

#include&nbsp;<cstring>

#include&nbsp;<cstdlib>

#include&nbsp;<queue>

#include&nbsp;<cmath>

#include&nbsp;<algorithm>

using namespace std;

const int maxn&nbsp;=&nbsp;123;

#define&nbsp;_x2(a)&nbsp;(a)&nbsp;*&nbsp;(a)

namespace Integral&nbsp;{

double (*func)(``double``);

double simpson(``double a, double b)&nbsp;{

double c&nbsp;=&nbsp;a&nbsp;+&nbsp;(b&nbsp;-&nbsp;a)&nbsp;/&nbsp;2;

return (func(a)&nbsp;+&nbsp;func(c)&nbsp;*&nbsp;4&nbsp;+&nbsp;func(b))&nbsp;*&nbsp;(b&nbsp;-&nbsp;a)&nbsp;/&nbsp;6;

}

double asr(``double a, double b, double eps, double A)&nbsp;{

double c&nbsp;=&nbsp;a&nbsp;+&nbsp;(b&nbsp;-&nbsp;a)&nbsp;/&nbsp;2;

double L&nbsp;=&nbsp;simpson(a,&nbsp;c),&nbsp;R&nbsp;=&nbsp;simpson(c,&nbsp;b);

if (``fabs``(L&nbsp;+&nbsp;R&nbsp;-&nbsp;A)&nbsp;<&nbsp;15&nbsp;*&nbsp;eps) return L&nbsp;+&nbsp;R&nbsp;+&nbsp;(L&nbsp;+&nbsp;R&nbsp;-&nbsp;A)&nbsp;/&nbsp;15;

return asr(a,&nbsp;c,&nbsp;eps&nbsp;/&nbsp;2,&nbsp;L)&nbsp;+&nbsp;asr(c,&nbsp;b,&nbsp;eps&nbsp;/&nbsp;2,&nbsp;R);

}

double getans(``double a, double b, double eps, double (*f)(``double``))&nbsp;{

func&nbsp;=&nbsp;f;

return asr(a,&nbsp;b,&nbsp;eps,&nbsp;simpson(a,&nbsp;b));

}

};

int k[maxn],&nbsp;a[maxn],&nbsp;b[maxn];

int A[maxn],&nbsp;B[maxn],&nbsp;C[maxn];

int ga,&nbsp;gb,&nbsp;gc,&nbsp;cnt;

double pos[12345];

double F(``double x)&nbsp;{

return ga&nbsp;*&nbsp;x&nbsp;*&nbsp;x&nbsp;+&nbsp;gb&nbsp;*&nbsp;x&nbsp;+&nbsp;gc;

}

double f(``double x)&nbsp;{

return sqrt``(1.0&nbsp;+&nbsp;_x2(2.0&nbsp;*&nbsp;ga&nbsp;*&nbsp;x&nbsp;+&nbsp;gb));

}

void add(``double x)&nbsp;{

if (x&nbsp;>&nbsp;0&nbsp;&&&nbsp;x&nbsp;<&nbsp;100)&nbsp;pos[cnt&nbsp;++]&nbsp;=&nbsp;x;

}

int main()&nbsp;{

#ifndef&nbsp;ONLINE_JUDGE

freopen``(``"in.txt"``, "r"``,&nbsp;stdin);

#endif&nbsp;//&nbsp;ONLINE_JUDGE

int T,&nbsp;n;

cin&nbsp;>>&nbsp;T;

while (T&nbsp;--)&nbsp;{

cnt&nbsp;=&nbsp;0;

pos[cnt&nbsp;++]&nbsp;=&nbsp;0;

pos[cnt&nbsp;++]&nbsp;=&nbsp;100;

cin&nbsp;>>&nbsp;n;

for (``int i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;n;&nbsp;i&nbsp;++)&nbsp;{

cin&nbsp;>>&nbsp;k[i]&nbsp;>>&nbsp;a[i]&nbsp;>>&nbsp;b[i];

A[i]&nbsp;=&nbsp;k[i];

B[i]&nbsp;=&nbsp;-2&nbsp;*&nbsp;k[i]&nbsp;*&nbsp;a[i];

C[i]&nbsp;=&nbsp;k[i]&nbsp;*&nbsp;a[i]&nbsp;*&nbsp;a[i]&nbsp;+&nbsp;b[i];

if (b[i]&nbsp;<&nbsp;100)&nbsp;{

double buf&nbsp;= sqrt``((100.0&nbsp;-&nbsp;b[i])&nbsp;/&nbsp;k[i]);

add(a[i]&nbsp;+&nbsp;buf);

add(a[i]&nbsp;-&nbsp;buf);

}

}

for (``int i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;n;&nbsp;i&nbsp;++)&nbsp;{

for (``int j&nbsp;=&nbsp;i&nbsp;+&nbsp;1;&nbsp;j&nbsp;<&nbsp;n;&nbsp;j&nbsp;++)&nbsp;{

ga&nbsp;=&nbsp;A[i]&nbsp;-&nbsp;A[j];

gb&nbsp;=&nbsp;B[i]&nbsp;-&nbsp;B[j];

gc&nbsp;=&nbsp;C[i]&nbsp;-&nbsp;C[j];

if (ga&nbsp;==&nbsp;0)&nbsp;{

if (gb&nbsp;!=&nbsp;0)&nbsp;add(-1.0&nbsp;*&nbsp;gc&nbsp;/&nbsp;gb);

continue``;

}

int d&nbsp;=&nbsp;gb&nbsp;*&nbsp;gb&nbsp;-&nbsp;4&nbsp;*&nbsp;ga&nbsp;*&nbsp;gc;

if (d&nbsp;>=&nbsp;0)&nbsp;{

add((-gb&nbsp;- sqrt``(1.0&nbsp;*&nbsp;d))&nbsp;/&nbsp;2.0&nbsp;/&nbsp;ga);

if (d)&nbsp;add((-gb&nbsp;+ sqrt``(1.0&nbsp;*&nbsp;d))&nbsp;/&nbsp;2.0&nbsp;/&nbsp;ga);

}

}

}

sort(pos,&nbsp;pos&nbsp;+&nbsp;cnt);

double ans&nbsp;=&nbsp;0;

for (``int i&nbsp;=&nbsp;1;&nbsp;i&nbsp;<&nbsp;cnt;&nbsp;i&nbsp;++)&nbsp;{

double L&nbsp;=&nbsp;pos[i&nbsp;-&nbsp;1],&nbsp;R&nbsp;=&nbsp;pos[i];

if (R&nbsp;-&nbsp;L&nbsp;<&nbsp;1e-10) continue``;

double M&nbsp;=&nbsp;(L&nbsp;+&nbsp;R)&nbsp;/&nbsp;2,&nbsp;minval&nbsp;=&nbsp;100;

int target&nbsp;=&nbsp;-1;

for (``int i&nbsp;=&nbsp;0;&nbsp;i&nbsp;<&nbsp;n;&nbsp;i&nbsp;++)&nbsp;{

ga&nbsp;=&nbsp;A[i];

gb&nbsp;=&nbsp;B[i];

gc&nbsp;=&nbsp;C[i];

if (F(M)&nbsp;<&nbsp;minval)&nbsp;{

minval&nbsp;=&nbsp;F(M);

target&nbsp;=&nbsp;i;

}

}

if (~target)&nbsp;{

ga&nbsp;=&nbsp;A[target];

gb&nbsp;=&nbsp;B[target];

gc&nbsp;=&nbsp;C[target];

ans&nbsp;+=&nbsp;Integral::getans(L,&nbsp;R,&nbsp;1e-8,&nbsp;f);

}

else ans&nbsp;+=&nbsp;R&nbsp;-&nbsp;L;

}

printf``(``"%.2f\n"``,&nbsp;ans);

}

return 0;

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章