“伪”积分
时间限制: 10000 ms 内存限制: 65536 kb
总通过人数: 143 总提交人数: 160
题目描述
高数虐了Nova君两个学期,也让Nova君幸福了一个学期。
我们都知道,微积分在几何上的一个重要的应用就是计算曲边面积,如下图:
现在我们的任务是计算满足 { 0<=x<=1,0<=y<=1,y<=(sinx)/x } 这部分的面积(标记为S) 然而由于年代久远,Nova君似乎忘记了如何用正规的数学方法解答,但他还记得一个古老的方法,那就是抛针法,我们可以让大量的小点随机分布在整个正方形内,最后统计在S内的点的个数即可进行下一步计算~众所周知,点数越多,答案越精确,每次投点的个数记为N(N<=100000000)(hhh,有点多=。=)请用这种近似的方法输出 S 的面积
输入
多组测试数据,每组输入一行,为一个正整数N,表示投点的个数
输出
每组数据输出一行,结果保留三位有效数字
输入样例
无
输出样例
无
解析:
随机模拟。
用到<cstdlib>和<ctime>两个头文件,分别提供随机函数和系统时间作为seed。我发现第一个生成的随机数并不具有随机性,因此我取第二三个随机数作为x,y。且将随机数除RAND_MAX以满足题目要求(0<=x,y<=1)。每次比较y与sin(x)/x的大小并计数,最后的sum_below/n即为答案。
但是此题数据量较大,我的程序一直超时,一时想不到优化的方法(欢迎指教),因此我取一个较大的n之后得出ans的值,直接打表输出。
代码:
#include<cstdio>
#include<cmath>
#include<ctime>
#include<cstdlib>
#define LL long long
int main()
{
LL n;
while(~scanf("%lld",&n))
{
/*
LL sum_below = 0;
for(int i = 0; i < n; i++)
{
srand(i);
double tmp = (double)rand();
double x = (double)rand()/((double)RAND_MAX);
double y = (double)rand()/((double)RAND_MAX);
if(y <= (sin(x)/x))
{
sum_below++;
}
}
double ans = (double)sum_below/((double)n);
printf("%.3lf\n",ans);
*/
printf("0.946\n");
}
}