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",& ...
随机推荐
- matconv-GPU 编译问题
如出现以下错误: 1 error detected in the compilation of "C:/Users/Justin/AppData/Local/Temp/tmpxft_0000 ...
- 理解Python中的__builtin__和__builtins__
以Python 2.7为例,__builtin__模块和__builtins__模块的作用在很多情况下是相同的. 但是,在Python 3+中,__builtin__模块被命名为builtins. 所 ...
- 初步了解CUDA(零)
初步了解CUDA,从历史开始,先不开发:
- 基于NABCD评论“欢迎来怼”团队Alpha版作品
NABCD分析 N(需求) 随着博客园网页版的出现,大家希望能够随时看自己博客,查看别人的博客,以及写博客,评论博客等功能.对于学生的我们,及时了解作业的动态很重要,电脑不能随时携带,但手机随身携带, ...
- Thunder团队第三周 - Scrum会议1
Scrum会议1 小组名称:Thunder 项目名称:i阅app Scrum Master:王航 工作照片: 杨梓瑞在拍照,所以不在照片中. 参会成员: 王航(Master):http://www.c ...
- JavaScript初探系列之Ajax应用
一 什么是Ajax Ajax是(Asynchronous JavaScript And XML)是异步的JavaScript和xml.也就是异步请求更新技术.Ajax是一种对现有技术的一种新的应用,不 ...
- Java容器之Iterator接口
Iterator 接口: 1. 所有实现了Collection接口的容器类都有一个iterator方法用以返回一个实现了Iterator接口的对象. 2. Iterator 对象称作迭代器,用以方便的 ...
- Alpha-2
前言 失心疯病源2 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 今天完成了那些任务 17:30~21:30 又测试了一些算法和代码,时间不能再拖下去了,要尽快进入代码阶段,决 ...
- lintcode-149-买卖股票的最佳时机
149-买卖股票的最佳时机 假设有一个数组,它的第i个元素是一支给定的股票在第i天的价格.如果你最多只允许完成一次交易(例如,一次买卖股票),设计一个算法来找出最大利润. 样例 给出一个数组样例 [3 ...
- C#通过SC命令和静态公共类来操作Windows服务
调用的Windows服务应用程序网址:http://www.cnblogs.com/pingming/p/5115304.html 一.引用 二.公共静态类:可以单独放到类库里 using Syste ...