poj.org/problem?id=3381
题意大概是
1. 圆柱形容器,底部有个面积s的洞, 侧面有m个面积不同的窟窿,同时侧面的窟窿的size很小,可以认为是0,也就是说窟窿所在的高度可以用一个数值表示
2. 底洞和侧面的窟窿溢出液体的速率取决于面积和液体的特性
3. 有n种液体,依次放入圆柱体内,每种液体有不同的特性,而且他们之间完全不相容
4. 要求输出每种液体从底部出口流出的体积
这题的数据量很小, m, n都<=10,完全可以直接暴力模拟整个过程,由于溢出的速率跟液体特性有关,所以需要把整个过程划分为不同的阶段,每个阶段内部,任意出口的液体都保持不变,而在不同段之间至少有一个出口的液体特性发生变化
所以问题归结为如何把整个过程划分,我是采用用时间来划分,那么如何确认每个段的时间长度呢? --> 可以用二分,如果时间过大,那么会检测出至少有一种液体的高度变化跨越了某个出口
实现
不确定是否有必要,我采用两个不同的误差, 一个误差控制二分的精度,另一个稍微大的误差来判断边界
k=0; while(1) {
while(k<n&&vs[k]<EPS2) k++; if (k==n) break;
j=0; x=0; vv=0; for (i=k; i<n; i++) {
x+=vs[i]/s;
d=0; while(j<=m) {
if (ck[j].x+EPS2>x) break;
d+=ck[j].d*as[i]; j++;
}
cx[i]=j-1;
cd[i]=d;
vv+=vs[i];
}
t=0; dt=vs[k]/cd[k];
while(dt>EPS) {
while(1) {
nt=t+dt; if (nt*cd[k]>vs[k]) break;
v=0; for (i=k; i<n; i++) {
v+=(vs[i]-nt*cd[i]);
if (cd[i]<EPS) continue;
x=v/s; j=cx[i]; if (x<ck[j].x) break;
}
if (i<n) break;
t=nt;
}
dt/=2;
}
t+=EPS;
rs[k]+=t*ck[0].d*as[k];
for (i=k; i<n; i++) vs[i]=vs[i]-t*cd[i];
}
不算难题