You are on page 1of 7

物理学在信息学的应用

by leokan
March 22, 2009

Contents
1 Introduction 2

2 Sample 1 2
2.1 brief . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.2 problem . . . . . . . . . . . . . . . . . . . . . . . . . 2
2.3 solution to the problem . . . . . . . . . . . . . . . . . 2
2.4 code . . . . . . . . . . . . . . . . . . . . . . . . . . . 2

3 Sample2 4
3.1 brief . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.2 problem . . . . . . . . . . . . . . . . . . . . . . . . . 4
3.3 solution to the problem . . . . . . . . . . . . . . . . . 4
3.4 code . . . . . . . . . . . . . . . . . . . . . . . . . . . 6

1
1 Introduction
物理学的应用十分广泛,在信息学中也有用武之地。这篇文章以两个范例演
示了一个物理学在信息学中的应用,望能抛砖引玉。
数据结构里面的pbt就是通过一个重量函数使得n叉树趋于平衡(需要通过转
换链上面的绳子来取消长链的存在),还有一些几何问题的特殊量可以用物理方
法求得。

2 Sample 1
2.1 brief
这是一个比较简单的问题,作为这个文章的一个热身题吧。

2.2 problem
leokan见到了一个排列整齐的迷宫,这个迷宫的路很不扎实,很可能断裂。
给出每条路的连接方式还有断裂的几率,括号包着的是并着的路,求leokan可
以通过迷宫的几率多大。
样例输入:
5 //总共的路径数
(A)(B,C,(D,E))
0.3 //该行和以下n行描述了断裂的几率
0.3
0.4
0.4
0.5
样例输出
0.7378 //通过的几率

2.3 solution to the problem


看到这样的题目,可以想到将模型转换为物理学的电路问题,即串连电路和
并联电路。
然后可以将并联的路求出断裂几率当成是一个串联的路来处理。

2.4 code

program problem1;
var
s : string;
p : array[’A’..’Z’] of double;
n : longint;

procedure init;

2
var
i : longint;
ch : char;
begin
readln(n);
readln(s);
ch:=’A’;
for i:=1 to n do
begin
readln(p[ch]);
inc(ch);
end;
end; { init }

function calc(x : string):double;


var
i,j,c : longint;
ans,tp : double;
begin
i:=1;
ans:=0;
while i<=length(x) do
begin
if x[i]=’(’ then
begin
tp:=1;
while x[i]=’(’ do
begin
c:=1;
j:=i;
while (c<>0) do
begin
inc(j);
if x[j]=’(’ then inc(c);
if x[j]=’)’ then dec(c);
end;
tp:=tp*calc(copy(x,i+1,j-i-1));
i:=j+1;
end;
ans:=ans+(1-ans)*tp;
continue;
end;
while (x[i]=’,’) and (i<=length(x)) do inc(i);
if (x[i] in [’A’..’Z’]) then
begin
ans:=p[x[i]]*(1-ans)+ans;

3
inc(i);
end;
end;
exit(ans);
end; { calc }

procedure work;
begin
writeln(1-calc(s):0:4);
end; { work }

begin
init;
work;
end.

3 Sample2
3.1 brief
这个问题是一个求代权平面几何图形最短路经的问题,可以转换为光录的最
短模型做。

3.2 problem
leokan在时间魔阵里面旅行,魔阵可以抽象成一个高为h,长为w矩形,这
个矩形可以被划分为许多高为h,长为wi的矩形,在第i个子矩形里 面旅行,所
经历的时间会乘上一个系数k,leokan行走速度是1m/s。
给出这个魔阵的数据,求leokan从魔阵左下脚到魔阵右上角的最短距离。
样例输入:
2 30 40
10 10
20 10
样例输出:
5.0000

3.3 solution to the problem


一个直观地想法是枚举交界的位置,求通过每个位置的直线距离*k的和,但
是这题涉及实数,不能枚举,则我们可以考虑二分,二分这个位置,复杂度将
是O((logm)n ),可以骗比较多的分。
标准的做法还是利用物理的模型解题。
光是很聪明的,它走的路线是花费的时间最短的路线(光在各个介质里面的
速度不一样,应此会折射选取最短时间的路线)。

4
有这个公式 sinθ sinθ2
v1 = v2 (斯涅尔定律),这个公式给出了光在两种介质的折
1

射角和它在两种介质的速度的关系。若假设leokan是一束光,但是在魔阵这种
特殊介质行进速度很慢,但是也能很聪明地用这种方法行进,则可以用最短的
时间走完全程。
知道了这个,我们只需要枚举leokan出发时的角度,判断这个角度下的最快
行进方式是否经过终点即可,同样,实数不可枚举,但是我们可以二分这个出
发的角度,从而求得最短路经。
是否觉得用这种物理方法解题很牵强呢?若是要证明,也可以抛开物理,用
数学方法证明这样的行进是最快的。
设想在每两个区域之间的行进状况。

f(x)为在区域1竖直移动x米,2个区域一共移动l米花费的时间。
q
p 2
2
w1 + x2 w22 + (l − x)
f (x) = + (1)
v1 v2

对f(x)求导
x (l − x)
f 0 (x) = p
2
− q (2)
v1 w1 + x2 2
v2 w22 + (l − x)

当函数取得极值的时候有
f 0 (x) = 0 (3)
此时有
x (l − x)
p = q (4)
v1 w12 + x2 v2 w22 + (l − x)
2


sinθ1 sinθ2
= (5)
v1 v2

5
3.4 code

program program2;
uses
math;

const
maxn = 100;
r0 = 1e-12;

var
wi,vi : array[1..maxn] of longint;
n,w,h : longint;

procedure init;
var
i,j : longint;
begin
readln(n,w,h);
for i:=1 to n do readln(wi[i],vi[i]);
j:=1;
for i:=2 to n do
if vi[i]<>vi[j] then
begin
inc(j);
vi[j]:=vi[i];
wi[j]:=wi[i];
end
else inc(wi[j],wi[i]);
n:=j;
end; { init }

function check(alpha : double):double;


var
h : double;
i : longint;
begin
h:=0;
for i:=1 to n-1 do
begin
h:=h+tan(alpha)*wi[i];
if sin(alpha)*vi[i+1]/vi[i]>1 then exit(maxlongint);
alpha:=arcsin(sin(alpha)*vi[i+1]/vi[i]);
end;
h:=h+tan(alpha)*wi[n];

6
exit(h);
end; { check }

procedure work;
var
l,r,mid,t : double;
i : longint;
begin
l:=0;
r:=pi/2;
while abs(l-r)>r0 do
begin
mid:=(l+r)/2;
if check(mid)>h then r:=mid else l:=mid;
end;
t:=0;
for i:=1 to n-1 do
begin
t:=t+(wi[i]/cos(l))/vi[i];
l:=arcsin(sin(l)*vi[i+1]/vi[i]);
end;
t:=t+(wi[n]/cos(l))/vi[n];
writeln(t:0:4);
end; { work }

begin
init;
work;
end.

You might also like