【ZOJ3921 2016年浙大2月月赛I】【物理题 底乘高积分式思维】In the Rain 圆柱体人行走 吸收雨体积

In the Rain Time Limit: 2 Seconds        Memory Limit: 65536 KB        Special Judge

Fujiwara no Mokou was formerly an ordinary human, but she became an immortal being after drinking the Hourai Elixir about 1300 years ago. She has some sort of control over fire.

【ZOJ3921 2016年浙大2月月赛I】【物理题 底乘高积分式思维】In the Rain 圆柱体人行走 吸收雨体积_第1张图片

One day, Mokou was on the way home after cutting bamboo. Suddenly it began to rain. As a manipulator of fire, Mokou dislikes rains. So she ran to her home as quickly as possible.

We can regard Mokou as a cylinder. The path can be simplified as a line. Mokou started from (0, 0, 0) and her home is at (x0, 0, 0). It is supposed that the rain is continuous and its density is 1. The rain will be absorbed immediately when it touches the surface of the cylinder or the ground. You need to measure how much weight of rain was absorbed by Mokou during her way to home in the rain.

Input

There are multiple cases. The first line of the input contains an integer T (1 ≤ T ≤ 200) which indicates the number of cases. For each test case:
The first line contains four integers R, H, V, x0, the radius, height and speed of the cylinder and the location of Mokou's house.
The second line contains three integers dx, dy and dz, the speed of the rain.
All integers in input are no less than -1000 and no larger than 1000. Test data satisfy that R, H, V, x0 > 0, dz < 0.

Output

For each case, output the total weight of rain which was absorbed by Mokou. Absolute or relative error no more than 1E-6 will be accepted. 

Sample Input

2
1 1 1 1
0 0 -1
2 3 3 3
2 3 -3

Sample Output

5.1415926536
75.6464437651

Reference

Fujiwara no Mokou


#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 0, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int casenum, casei;
const double PI = acos(-1.0);
double r, h, v, x0;
double dx, dy, dz;
int main()
{
	scanf("%d", &casenum);
	for (int casei = 1; casei <= casenum; ++casei)
	{
		scanf("%lf%lf%lf%lf", &r, &h, &v, &x0);
		scanf("%lf%lf%lf", &dx, &dy, &dz); dx -= v;
		double t = x0 / v;
		double ans = (PI*r*r*-dz + 2 * r*h*sqrt(dx*dx + dy*dy))*t;
		printf("%.15f\n", ans);
	}
	return 0;
}
/*
【trick&&吐槽】
积分式思维,不同方向的分解与合成,还是非常重要的啊。

【题意】
一个人,可以被看做为圆柱,半径为r,高为h,速度为v,
在三维坐标系(x,y,z)中,从(0,0,0)走到(x0,0,0)

雨是连续的,密度为1,落到人或地面上立刻就消失。
我们需要算出,这个人在雨中的行走过程中,能吸收多少重量的雨。

告诉你雨,是以其(dx,dy,dz)的速度的形式告知的。
数据保证x0>0,dz<0。

【类型】
物理题

【分析】
要有相对运动的思想。
这个人运动,雨也运动,研究起来稍微复杂。
我们不妨把人设为静止的,得到在这种条件下雨的相对速度,得到这个相对速度之后,我们就完全不要考虑之前的速度了。

我们发现,这个人的头上必然是会被淋到雨的。对答案的贡献是头面积*纵向速度*时间。
然后,这个人身体方向也是可能被淋到雨的(只要dx不为0)

我们假设我们得到了它被雨淋的底面积,我们现在有一个方向向量(表示速度),同时还有时间,
那么我们按照这个方向向量移动(速度*时间)的距离,就得到了一个立体图形。
而这个立体图形的体积,显然就是这个人的身体侧面吸收雨的体积。

而这个体积怎么求呢?要用底乘高,高显然要与底垂直。而y这个方向,显然必然与底面平行。
于是高的长度其实是sqrt(x*x+y*y),方向向量为(x,y,0)
而底面积是多少呢?我们沿着这个高的方向打到这个圆柱体,得到的是一个2rh的面积,也就对应着底面积

于是,侧面吸收雨的体积是2*r*h*sqrt(x*x+y*y)
于是,答案是(PI*r*r*-dz+2*r*h*sqrt(x*x+y*y))*t

【时间复杂度&&优化】
O(1)


*/

你可能感兴趣的:(题库-ZOJ,积分相关)