POJ3381 模拟|二分

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];
    }

不算难题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值