题目是让求两个椭圆交集的面积,acm省赛的倒数第二题。
官方蒙特卡洛算法的题解:
我们可以选定一个矩形框柱两个椭圆,在这个矩形内均匀撒点,设一共撒了 K个点,有 F个点落在了椭圆内,矩形的面积即为 S,那我们可以近似的认为两个椭圆的并的面积为 F/K*S。使矩形的面积尽量小,撒尽量多的点(使 尽量大),就可以通过此题了。
题目中的数据范围是(-8,8),于是在这个范围内均匀取点,每个点相隔0.01单位,如果这个点落在椭圆内,计数加一,最后除以点的总数(1600×1600),再乘矩形面积(16×16),就是椭圆相交的面积。
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
int main()
{
int n;
scanf("%d",&n);
while(n--){
double a,b,c,d,ans=0;
cin>>a>>b>>c>>d;
for(double i=-8;i<=8;i+=0.01){
for(double j=-8;j<=8;j+=0.01){
if(i*i/a/a+j*j/b/b<=1||i*i/c/c+j*j/d/d<=1){//注意分母要分别除
ans++;
}
}
}
printf("%.1f\n",ans/10000);//10000=1600*1600/(16*16)
}
return 0;
}