POJ3737 UmBasketella

嘟嘟嘟

 

一道三分入门题。

参考二分,三分就是每一次把区间分成三段,然后舍弃一段,不断缩小范围直到一个点。

一般用于求单峰函数的最值问题。

这道题发现V和r成一次函数的关系,因此三分r。

下面给出三分板子。其实三分的m1, m2没必要把区间分成均等的三份,只不过这样写的方便。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<vector>
 9 #include<stack>
10 #include<queue>
11 using namespace std;
12 #define enter puts("") 
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 const db Pi = acos(-1.0);
21 //const int maxn = ;
22 inline ll read()
23 {
24   ll ans = 0;
25   char ch = getchar(), last = ' ';
26   while(!isdigit(ch)) {last = ch; ch = getchar();}
27   while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
28   if(last == '-') ans = -ans;
29   return ans;
30 }
31 inline void write(ll x)
32 {
33   if(x < 0) x = -x, putchar('-');
34   if(x >= 10) write(x / 10);
35   putchar(x % 10 + '0');
36 }
37 
38 db S, r;
39 
40 db calc(db r)
41 {
42   db l = (S - Pi * r * r) / (Pi * r);
43   db h = sqrt(l * l - r * r);
44   return Pi * r * r * h / 3.00;
45 }
46 
47 int main()
48 {
49   while(scanf("%lf", &S) != EOF)
50   {
51       db L = 0, R = sqrt(S / Pi);
52       for(int i = 1; i <= 1000; ++i)
53         {
54           db m1 = L + (R - L) / 3.00;
55           db m2 = R - (R - L) / 3.00;
56           if(calc(m1) <= calc(m2)) L = m1, r = m2;
57           else R = m2, r = m1;
58         }
59       db l = (S - Pi * r * r) / (Pi * r);
60       db h = sqrt(l * l - r * r);
61       db V = Pi * r * r * h / 3.00;
62       printf("%.2f\n%.2f\n%.2f\n", V, h, r);
63     }
64   return 0;
65 }
View Code

 

posted @ 2018-10-18 07:45  mrclr  阅读(183)  评论(0编辑  收藏  举报