zoj 2369 Two Cylinders
zoj 2369 Two Cylinders
链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2369
题意:已知两个无限长的圆柱的半径,它们轴线相交且垂直,求相交部分的体积。
思路:以相交点为坐标原点,建立三维坐标系,列出 两个圆柱的公式,把三维转化为一维积分公式
V1 : x2 + y2 = r12 ==> y = sqrt ( r12 - x2 );
V2 : x2 + z2 = r22 ==> z = sqrt ( r22 - x2 );
V = ∫∫∫ dv = ∫∫∫ dxdydz = ∫(∫∫ dydz)dx 积分区间:( 0 <= x <= r1 , 0 <= x <= r2 )
所以: V = ∫0min(r1, r2) sqrt(( r12-x2) * (r22-x2));
计算这个积分,我用了好几种方法,但是只有 变步长simpon 积分达到精度要求,我也不清楚什么原因。下面是几种求积分的算法:
测试数据:
10
1 1
2 1
3 2
5 2
8 3
8 4
99 2
99 56
84 31
91 17
正确答案:
5.3333
12.1603
70.9361
123.0975
444.2909
778.2605
2488.0144
1869197.4256
498415.2860
164517.4621
变步长 simpon 积分:(得到正确结果)
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <cstring>
#include <math.h>
using namespace std; const double eps = 1e-;
double r1, r2; double f(double x)
{
return . * sqrt((r1*r1 - x*x) * (r2*r2 - x*x));
} double simpson(double a, double b)
{
int n, k;
double h, t1, t2, s1, s2, ep, p, x;
n = , h = b - a; t1 = h * ( f(a) + f(b) ) / .; //计算T1 = (b-a)/2*[f(a) + f(b)]
s1 = t1; //T1代替S1
ep = eps + .;
while(ep >= eps)
{
p = ;
for(k = ; k <= n-; k++)
{
x = a + (k + 0.5) * h;
p += f(x);
}
t2 = (t1 + h * p) / .; //计算T2n = Tn/2 + h/2 * [(累加)f(xk + 0.5)];
s2 = (. * t2 - t1) / .; //计算Sn = (4*Tn - Tn) / 3;
ep = fabs(s2 - s1); //计算精度
t1 = t2, s1 = s2, n += n, h /= .;
}
return s2;
} int main()
{
int CASE;
freopen("zoj2369.txt", "r", stdin);
cin >> CASE;
while(CASE--)
{
scanf("%lf%lf", &r1, &r2);
if(r2 < r1) swap(r1, r2);
double t = simpson(., r1);
printf("%.4lf\n", t); }
return ;
} /* 结果:
5.3333
12.1603
70.9361
123.0974
444.2908
778.2604
2488.0144
1869197.4256
498415.2860
164517.4621
*/
勒让德-高斯求积(精度不够):
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <cstring>
#include <math.h>
using namespace std; const double eps = 1e-;
double r1, r2; double f(double x)
{
return . * sqrt((r1*r1 - x*x) * (r2*r2 - x*x));
} double lrgs(double a, double b)
{
int m, i, j;
double s, p, ep, aa, bb, w, x, g, h;
static double t[] = {-0.9061798459, -0.5384693101, 0.0, 0.5384693101, 0.9061798459};
static double c[] = {0.2369268851, 0.4786286705, 0.5688888889, 0.4786286705, 0.2369268851};
m = ;
h = b - a; s = fabs(0.001 * h);
p = 1.0e+35, ep = eps + 1.0;
while(ep >= eps && fabs(h) > s)
{
g = .;
for(i = ; i <= m; i++)
{
aa = a + (i-.) * h, bb = a + i * h;
w = .;
for(j = ; j < ; j++)
{
x = ((bb - aa) * t[j] + (bb + aa)) / .;
w += f(x) * c[j];
}
g += w;
}
g = g * h / .;
ep = fabs(g-p) / (. + fabs(g));
p = g, m += , h = (b-a) / m;
}
return g;
} int main()
{
int t;
freopen("zoj2369.txt", "r", stdin);
scanf("%d", &t);
while(t--)
{
scanf("%lf%lf", &r1, &r2);
if(r1 > r2) swap(r1, r2);
printf("%.4lf\n", lrgs(, r1));
}
return ;
} /*结果
5.3333
12.1619
70.9440
123.1138
444.3504
778.3592
2488.3679
1869425.2091
498482.1853
164540.5195
*/
龙贝格求积法(精度不够):
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <vector>
#include <cstring>
#include <math.h>
using namespace std; const double eps = 1e-;
double r1, r2; double f(double x)
{
return . * sqrt((r1*r1 - x*x) * (r2*r2 - x*x));
} double romb(double a, double b)
{
int n, m, i, k;
double y[], h, ep, p, x, s, q;
h = b - a;
y[] = h * ((f(a) + f(b))) / .;
m = , n = , ep = eps + 1.0;
while(ep >= eps )
{
p = 0.0;
for(i = ; i < n; i++)
{
x = a + (i+0.5) * h;
p += f(x);
}
p = (y[] + h * p) /.;
s = 1.0;
for(k = ; k <= m; k++)
{
s = . * s;
q = (s*p - y[k-]) / (s - .);
y[k - ] = p, p = q;
}
ep = fabs(q - y[m-]);
m = m + , y[m - ] = q, n += n, h /= .;
}
return q;
} int main()
{
int t;
freopen("zoj2369.txt", "r", stdin);
freopen("zzin1.txt", "w", stdout);
scanf("%d", &t);
while(t--)
{
scanf("%lf%lf", &r1, &r2);
if(r1 > r2) swap(r1, r2);
printf("%.4lf\n", romb(, r1));
}
return ;
} /*结果
5.3333
12.1529
70.8978
123.0697
444.1897
778.0925
2487.8023
1869191.3654
498410.2627
164515.7323
*/
也不知最后两个代码那里写搓了,真心无力。
下面给出标程:
#include <cmath>
#include <cstdio>
#include <algorithm> using namespace std; const long double H = 5e-; struct F {
long double rr1, rr2;
F(long double r1, long double r2) : rr1(r1 * r1), rr2(r2 * r2) {
}
long double operator()(long double x) const {
x = x * x;
return sqrt((rr2 - x) * (rr1 - x));
}
}; int main() {
int re; scanf("%d", &re);
for (int ri = ; ri <= re; ++ri) {
long double r1, r2;
scanf("%Lf%Lf", &r1, &r2);
if (r1 > r2) {
swap(r1, r2);
}
int n = int(r1 / H);
// int n = 1000000;
long double h = r1 / n / ;
F f(r1, r2);
long double s = ;
s += f() + f(r1);
for (int i = ; i < * n; ++i) {
if (i & ) {
s += * f(i * h);
} else {
s += * f(i * h);
}
}
s /= * n;
s *= * r1;
printf("%.6Lf\n", s);
} return ;
}
网上看的大牛的代码,0ms秒过,我的用了290ms, 标程用了310ms
#include <cstdio>
#include <cmath>
#include <algorithm>
using namespace std; #define db double
#define rt return
#define cs const cs db eps = 1e-;
inline int sig(db x){rt (x>eps)-(x<-eps);} db r1, r2; inline db f(db x) {
rt . * sqrt(r1*r1-x*x) * sqrt(r2*r2-x*x);
} inline db simpson(db a, db b) {
rt (b-a)*(f(a) + .*f((a+b)/.) + f(b)) / .;
} inline db calc(db a, db b, int depth) {
db total = simpson(a, b), mid = (a+b) / .;
db tmp = simpson(a, mid) + simpson(mid, b);
if(sig(total-tmp) == && depth > ) rt total;
rt calc(a, mid, depth + ) + calc(mid, b, depth + );
} int main() {
// freopen("std.in", "r", stdin);
int T;
freopen("zoj2369.txt", "r", stdin);
scanf("%d", &T);
while(T--) {
scanf("%lf%lf", &r1, &r2);
if(sig(r1-r2) > ) swap(r1, r2);
printf("%.4lf\n", . * calc(., r1, ));
}
rt ; }
zoj 2369 Two Cylinders的更多相关文章
- POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat 二分)
POJ 2296 Map Labeler / ZOJ 2493 Map Labeler / HIT 2369 Map Labeler / UVAlive 2973 Map Labeler(2-sat ...
- ZOJ题目分类
ZOJ题目分类初学者题: 1001 1037 1048 1049 1051 1067 1115 1151 1201 1205 1216 1240 1241 1242 1251 1292 1331 13 ...
- ZOJ People Counting
第十三届浙江省大学生程序设计竞赛 I 题, 一道模拟题. ZOJ 3944http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=394 ...
- ZOJ 3686 A Simple Tree Problem
A Simple Tree Problem Time Limit: 3 Seconds Memory Limit: 65536 KB Given a rooted tree, each no ...
- ZOJ Problem Set - 1394 Polar Explorer
这道题目还是简单的,但是自己WA了好几次,总结下: 1.对输入的总结,加上上次ZOJ Problem Set - 1334 Basically Speaking ac代码及总结这道题目的总结 题目要求 ...
- ZOJ Problem Set - 1392 The Hardest Problem Ever
放了一个长长的暑假,可能是这辈子最后一个这么长的暑假了吧,呵呵...今天来实验室了,先找了zoj上面简单的题目练练手直接贴代码了,不解释,就是一道简单的密文转换问题: #include <std ...
- ZOJ Problem Set - 1049 I Think I Need a Houseboat
这道题目说白了是一道平面几何的数学问题,重在理解题目的意思: 题目说,弗雷德想买地盖房养老,但是土地每年会被密西西比河淹掉一部分,而且经调查是以半圆形的方式淹没的,每年淹没50平方英里,以初始水岸线为 ...
- ZOJ Problem Set - 1006 Do the Untwist
今天在ZOJ上做了道很简单的题目是关于加密解密问题的,此题的关键点就在于求余的逆运算: 比如假设都是正整数 A=(B-C)%D 则 B - C = D*n + A 其中 A < D 移项 B = ...
- ZOJ Problem Set - 1001 A + B Problem
ZOJ ACM题集,编译环境VC6.0 #include <stdio.h> int main() { int a,b; while(scanf("%d%d",& ...
随机推荐
- Spark- 根据IP获取城市(java)
开源 IP 地址定位库 ip2region 1.4 ip2region 是准确率 99.9% 的 IP 地址定位库,0.0x毫秒级查询,数据库文件大小只有 2.7M,提供了 Java.PHP.C.Py ...
- Linear Equations in Linear Algebra
Linear System Vector Equations The Matrix Equation Solution Sets of Linear Systems Linear Indenpende ...
- LeetCode - 459. Repeated Substring Pattern - O(n)和O(n^2)两种思路 - KMP - (C++) - 解题报告
题目 题目链接 Given a non-empty string check if it can be constructed by taking a substring of it and appe ...
- 【转载】2015Android 面试题 01
1.如何避免ANR? 答:ANR:Application Not Responding,五秒在Android中,活动管理器和窗口管理器这两个系统服务负责监视应用程序的响应. 当出现下列情况时,Andr ...
- scatter注记词2
couch ranch bind ski extra bring note embrace tape they stick legend
- java报错:Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE
Exception in thread "main" java.lang.NoSuchFieldError: INSTANCE at org.apache.http.conn.ss ...
- python学习摘要(3)--字符串处理函数
python没有字符类型, "字符串" '字符串' '''字符串''' """字符串""" 三引号可以支持字符串跨行 字 ...
- 【IdentityServer4文档】- 欢迎来到 IdentityServer4
欢迎来到 IdentityServer4 IdentityServer4 是一款包含和实现了 OpenID Connect 和 OAuth 2.0 协议的,适用于 ASP.NET Core 的框架 . ...
- 全排列 next_permutation() 函数的用法
在头文件<algorithm>里面有如下代码: int a[]; do { } while(next_permutation(a,a+n)); 可产生1~n的全排列有如下代码: #incl ...
- js控制input只能输入数字和小数点后两位,输入其他自动清除方法。
工作中input='text'总会遇到要控制输入数字,或者是输入中文,输入电话,输入身份证号,邮箱等.今天我遇到的是要输入数字并且只能小数点后面两位的数字,还不能为负数.废话不多说上代码: <i ...