[ZOJ1021] The Willy Memorial Program

【题目大意】


有一些竖直的圆筒状管子,管子间有理想的水平细管相连。一只蜘蛛停在某跟管子的某个高度上,从第一根管子往系统注水,问前往营救的老鼠有多长时间可以关闭热水阀门。

    最终抽象为当水上升到指定位置的时候系统中的总水柱高度。

 

【解题思路】

 AC思路:

(参考“狗狗40题搞完纪念“)从第一根管子开始注水,采用优先队列的方式每次选取可注水且纵坐标最大(最低)的地方进行注水。若中途出现溢出现象,则永远都淹不到蜘蛛啦。

WA思路:

假设可以淹到蜘蛛,则蜘蛛所在管子的水柱高为其所在高度。从蜘蛛所在的管子根据管子的水平相连关系通过DFS的方式注水,看能否注水到第一根管子。注水途中判断是否溢出。

 

【解题吐槽】

WA了一个下午,决定还是在考完数理逻辑的下午不要太自虐。看了“狗狗40题搞完纪念“里的源码,把set、list、priority_queue的基本操作复习了一下。然后照着源代码的思路自己重新写了一遍(没有技术含量了╮(╯▽╰)╭)

物理不好还牵扯到做OJ呀,真的是o(╯□╰)o

  

【源代码】

/*
ZOJ1021
参考“狗狗40题搞完纪念“标程 
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <set>
#include <list>
#include <queue>
#include <cstdio>
#include <utility>
using namespace std;
#define maxp 30

int main()
{
    int cases, pipes, links, target, level, tot_water;
    int w,p,pp;
    int px[maxp], py[maxp], bottom[maxp], water[maxp];
    bool find_ans;
    set<int> link;
    list<pair<int, int> > e[maxp];
    priority_queue<pair<int, int> > pq;
    
    scanf("%d", &cases);
    while (cases--)
    {
        //read data
        scanf("%d", &pipes);
        for (int i=0; i<pipes; i++)
        {
            int tmp;
            scanf("%d%d%d", &px[i], &py[i], &tmp);
            bottom[i]=py[i]+tmp;    //bottom y-coordinate of the pipe
            water[i]=-1;            //means !visit pipe i
            e[i].clear();
        }
        scanf("%d", &links);
        link.clear();
        for (int i=0; i<links; i++)
        {
            int lx, ly, len, lk1=-1, lk2=-1;
            scanf("%d%d%d", &lx, &ly, &len);
            for (int j=0; j<pipes; j++)
                if (bottom[j]>=ly && py[j]<=ly)
                {
                    if (px[j]+1==lx) lk1=j;
                    if (px[j]==lx+len) lk2=j;
                    if (lk1!=-1 && lk2!=-1)
                    {
                        break;
                    }
                }
            link.insert(ly);
            e[lk1].push_back(make_pair(ly, lk2));
            e[lk2].push_back(make_pair(ly, lk1));
        }
        scanf("%d%d", &target, &level);
        link.insert(level);
        target--;
        //initial part
        if (level<py[target]) 
        {
            printf("No Solution\n");
            continue;
        }
        if (py[target]<=level && level<=bottom[target])
            e[target].push_back(make_pair(level, -2));
        for (int i=0; i<pipes; i++)
        {
            for (set<int>::const_iterator j=link.lower_bound(py[i]);
                 j!=link.end()&&*j<bottom[i]; j++)
            {
                e[i].push_back(make_pair(*j, i));
            }
            e[i].push_back(make_pair(py[i], -1));
            e[i].sort();
            e[i].reverse();
        }
        while (!pq.empty())
            pq.pop();
        water[0]=bottom[0];
        pq.push(make_pair(water[0], 0));
        find_ans=false;
        tot_water=0;
        //solve part
        while (!pq.empty())
        {
            w=pq.top().first;   //water   
            p=pq.top().second;  //pipe
            pq.pop();
            if (p==-1)
                break;
            else if (p==-2)
            {
                find_ans=true;
                break;
            }
            tot_water+=(water[p]-w);
            water[p]=w;
            while (!e[p].empty() && e[p].front().first==water[p])
            {
                pp=e[p].front().second;
                if (pp<0)
                {
                    pq.push(e[p].front());
                }
                else if (water[pp]==-1)
                {
                    water[pp]=bottom[pp];
                    pq.push(make_pair(water[pp], pp));
                }
                e[p].pop_front();
            }
            if (!e[p].empty())
            {
                pq.push(make_pair(e[p].front().first, p));
            }
        }
        if (find_ans)
            printf("%d\n", tot_water);
        else
            printf("No Solution\n");
    }
    return 0;
}
        
            


 

 

————————————解题参考————————————

1、set标准库

2、list标准库

 标准模板库(STL)学习探究之List容器

http://blog.youkuaiyun.com/sun_top/archive/2009/05/24/4212998.aspx

3、priority_queue标准库

  标准模板库(STL)学习探究之List容器

http://blog.youkuaiyun.com/sun_top/archive/2009/05/25/4213413.aspx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值