[Contest20180418]物理竞赛

本文探讨了一个三维空间中凸透镜与多个点光源的光学问题,分析了不同条件下圆形光屏接收光强度的最大值,并提供了相应的算法实现。

题意:在一个三维空间中有一个轴,轴上有一个垂直于轴的半径为$R$的凸透镜(光心在轴上)和$n$个点光源,假设每个点光源发出的$1$单位光都刚好覆盖凸透镜,现在有一个半径为$r$的圆形光屏,问光屏最多能接收到多少单位光

首先当光屏与轴垂直且圆心在轴上时才能取到最优解

显然当$r\geq R$时答案是$n$

设光心的坐标为$0$,$n$个点光源的坐标为$x_{1\cdots n}(x_i\lt0)$,成像在$u_{1\cdots n}$处,光屏的坐标为$x(x\geq0)$,考虑每个点光源有多少光照到光屏上

对于第$i$个点光源,如果$x_i=-f$,那么$u_i=+\infty$,光线经过透镜后平行于轴,贡献为$\left(\dfrac rR\right)^2$

如果$x_i\ne-f$,那么$u_i=\dfrac1{\frac1f-\frac1{x_i}}$,贡献为$g_i(x)=\min\left(\left(\dfrac{u_ir}{(u_i-x)R}\right)^2,1\right)$,这玩意儿随$x$变化的图像大概长这样

(青蛙子???)

以所有红点为端点把$x$分段,那么所有$g_i(x)$在每一段的二阶导数都是连续且$\geq0$的,所以$\begin{align*}\sum\limits_{i=1}^ng_i(x)\end{align*}$在每一段都是凹的,也就是说最大值只可能在这些点上取到,直接枚举这些点,计算答案取最大值即可

最后还要和$x=0$的答案取$\max$,因为如果光线发散,光屏越靠近凸透镜答案越大

#include<stdio.h>
typedef double du;
const du eps=1e-7;
int x[1010],n,f,R,r;
du u[1010];
du min(du a,du b){return a<b?a:b;}
du max(du a,du b){return a>b?a:b;}
du abs(du x){return x>0?x:-x;}
du sqr(du x){return x*x;}
du calc(du t){
	int i;
	du res;
	res=0;
	for(i=1;i<=n;i++){
		if(x[i]==-f)
			res+=r*r/du(R*R);
		else if(abs(u[i]-t)>eps)
			res+=min(sqr(u[i]*r/du((u[i]-t)*R)),1);
		else
			res+=1.;
	}
	return res;
}
int main(){
	int i;
	du ans;
	scanf("%d%d%d%d",&n,&f,&R,&r);
	if(r>=R){
		printf("%d",n);
		return 0;
	}
	for(i=1;i<=n;i++){
		scanf("%d",x+i);
		if(x[i]!=-f)u[i]=1./(1./du(f)+1./du(x[i]));
	}
	ans=calc(0);
	for(i=1;i<=n;i++){
		if(x[i]<-f)ans=max(ans,max(calc(u[i]*(R-r)/du(R)),calc(u[i]*(R+r)/du(R))));
	}
	printf("%.7lf",ans);
}

转载于:https://www.cnblogs.com/jefflyy/p/8875827.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值