Description

Willy the spider used to live in the chemistry laboratory of Dr. Petro. He used to wander about the lab pipes and sometimes inside empty ones. One night while he was in a pipe, he fell asleep. The next morning, Dr. Petro came to the lab. He didn't notice Willy while opening the valve to fill the pipes with hot water. Meanwhile, Stanley the gray mouse got what was going to happen. No time to lose! Stan ran hard to reach the valve before Willy gets drawn, but... Alas! He couldn't make it!

Poor Willy was boiled in hot water, but his memory is still in our hearts. Though Stan tried his best, we want to write a program, in the memory of Willy, to compute the time Stan had, to rescue Willy, assuming he started to run just when the doctor opened the valve.

To simplify the problem, assume the pipes are all vertical cylinders with diameter 1 cm. Every pipe is open from the top and closed at the bottom. Some of the pipes are connected through special horizontal pipes named links. The links have very high flow capacity, but are so tiny that at any given time, the volume of water inside them is negligible. The water enters from top of one of the pipes with a constant rate of 0.25PI cm3/sec and begins to fill the pipe from the bottom until the water reaches a link through which it flows horizontally and begins to fill the connected pipe. From elementary physics we know if two pipes are connected and the surface of the water is above the connecting link, the level of water in both pipes remains the same when we try to fill one of them. In this case the water fills each pipe with a rate equal to half of the rate of incoming water. As an example, consider the following configuration: 

First, the lower 2 centimeters of the left pipe is filled with water at full rate, then, the lower 3 centimeters of the right pipe is filled, and after that, the upper part of the two pipes are filled in parallel at half rate. The input to your program is a configuration of pipes and links, and a target level in one of the pipes (the heavy dotted line in the above figure). The program should report how long it takes for the level of water to reach the target level. For the above configuration, the output is 9 seconds.

It is assumed that the water falls very rapidly, such that the time required for the water to fall can be neglected. The target level is always assumed to be a bit higher than the specified level for it. As an example, if we set the target point to level 4 in the left pipe in the figure above, the elapsed time for water to reach that target is assumed to be 5 (not 2), Also note that if the water reaches to the top of a pipe (say in level x), it won't pour out outside the pipe until empty spaces in connected pipes below level x are filled (if can be filled, i.e. the level of water reaches the connecting links). (Note that there may be some links at level x, to which water is entered). After all such spaces are filled; the water level would not go up further.

Input

To describe positions, we assume the coordinates are expressed as (x, y) and the origin lies in the top-left of all pipes and links. (Note that y coordinates are increased downwards). All coordinates are integer numbers between 0 and 100, inclusive. 
The first line of the input file contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case is p (1 <= p <= 20), the number of pipes, followed by p lines, each describing a pipe. Each pipe description line consists of three numbers. The first two are (x, y) coordinates of the upper-left corner of the pipe and the third number is the height of the pipe (at least 1 cm and at most 20 cm). Note that diameter of each pipe is 1 cm.

After input data describing the pipes, there is a line containing a single integer l, which is the number of links (0 <= l <= 50). After it, there are l lines describing links. Each link description contains 3 integers. The first two are (x, y) coordinates of the left end-point of the link and the third is the length of the link (at least 1 cm and at most 20 cm). It is assumed that the width of the link is zero.

The last line for each test case contains two numbers. The first is the number of target pipe (starting from one, with the order appeared in test data). The second line is the desired y for the level of water in the target pipe (note that the specified level may be out of the pipe at all).

You can assume the following about the input: 
. The water enters into the first pipe. 
. No link crosses a pipe. 
. No two links have the same y coordinates. 
. No two pipes have the same upper-left x coordinates. 
. Both endpoints of each link are connected to pipes. 

Output

The output should contain exactly t lines with no blank lines in between, each corresponding to one test case. Each output line should contain the time required for the water to reach the target level in the target pipe (an integer number). If in a specific test case, the water never reaches the target level, the line should contain No Solution string in it.

Sample Input

1
2
2 0 6
5 1 6
1
3 4 2
2 2

Sample Output

9

Source

 

题目大意:有一些竖直的圆筒状管子,管子间有理想的水平细管相连。一只蜘蛛停在某跟管子的某个高度上,从第一根管子往系统注水,问前往营救的蜘蛛有多长时间可以关闭热水阀门。最终抽象为当水上升到指定位置的时候系统中的总水柱高度。这里第一行数据表示有t种情况,接下来2表示有2个管子,第三行和第四行分别表示这2个管子的左上角坐标和管子的长度,下面的1表示有1个连接,该链接左端坐标(3,4),长为2,接下来的2,2表示蜘蛛在第2号管子的y=2处。

解题思路:从第一根管子开始注水,采用优先队列的方式每次选取可注水且纵坐标最大(最低)的地方进行注水。若中途出现溢出现象(从其他管子的上端流出),则永远都淹不到蜘蛛。

相关知识:pair 的用法              http://www.cnblogs.com/Nimeux/archive/2010/10/05/1844191.html

lower_bound的用法  http://blog.csdn.net/niushuai666/article/details/6734403

 
 #include <iostream>
#include <cstring>
#include <string>
#include <string.h>
#include <set>
#include <list>
#include <queue>
using namespace std;
#define maxp 30 int cases,pipes,links,target,level,tot_water;
int w,p,pp;
int px[maxp],py[maxp],bottom[maxp],water[maxp];//一个管道内x,上面y,下面y,当前水位
bool find_ans;
set<int> link;//保存连接的y值
list<pair<int, int> > e[maxp];//保存管i上的连接的位置和另一端的管的编号
priority_queue<pair<int, int> > pq;//保存当前水位(y值和管道标号) void read(){
cin>>pipes;//输入管道
for(int i=;i<pipes;i++){
int tmp;
cin>>px[i]>>py[i]>>tmp;
bottom[i]=py[i]+tmp; //管i的底部y值
water[i]=-; //标记means !visit pipe i
e[i].clear();
}
cin>>links;//输入连接
link.clear();
for(int i=;i<links;i++){
int lx,ly,len,lk1=-,lk2=-;
cin>>lx>>ly>>len;//输入每个连接并计算该连接连的管道lk1,lk2
for(int j=;j<pipes;j++){
if(bottom[j]>=ly && py[j]<=ly){
if(px[j]+==lx)lk1=j;
if(px[j]==lx+len)lk2=j;
if(lk1!=- && lk2!=-)break;
}
}
link.insert(ly);
e[lk1].push_back(make_pair(ly, lk2));
e[lk2].push_back(make_pair(ly, lk1));
}
cin>>target>>level;
link.insert(level);//把蜘蛛的位置也传入连接!!!
target--;
}
bool init(){
if(level<py[target]){
cout<<"No Solution\n";
return ;
}//当蜘蛛在管道外时,无解
//如果蜘蛛位于target管道中就虚拟一个target和-2管相连的连接(-2可以起到标记作用)
if(py[target]<=level && level<=bottom[target])
e[target].push_back(make_pair(level,-));
//延长每条连接把与每个管道的交点保存成i和i管相连的连接的形式
//把每个管道的上端标记为其和-1相连的形式,并把e[i]排序颠倒
for(int i=;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],-));
e[i].sort();
e[i].reverse();
}
return ;
}
void solve(){
while (!pq.empty())pq.pop();//清空pq
water[]=bottom[];
pq.push(make_pair(water[],));//从第一个管道开始倒水
find_ans=false;
tot_water=;
while (!pq.empty()){
w=pq.top().first; //water
p=pq.top().second; //pipe
pq.pop();
if(p==-)break;//溢出
else if(p==-){//淹没
find_ans=true;
break;
}
tot_water+=(water[p]-w);//把p管流到w位置
water[p]=w;
//把当前w位置所有与p连接的处理
while(!e[p].empty() && e[p].front().first==water[p]){
pp=e[p].front().second;
if(pp<)pq.push(e[p].front());//如果不是实连接(-1,-2的情况)直接放入pq中
else if(water[pp]==-){//如果实连接且还没有水,就更新该管水位,并放入pq中
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));//如果p管还有连接,就把它放入pq中
}
}
int main(){
cin>>cases;
while (cases--){
read();
if(!init())continue;
solve();
if (find_ans)
cout<<tot_water<<'\n';
else
cout<<"No Solution\n";
}
return ;
}
 
 
 

[ACM_模拟] The Willy Memorial Program (poj 1073 ,联通水管注水模拟)的更多相关文章

  1. poj 1008:Maya Calendar(模拟题,玛雅日历转换)

    Maya Calendar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64795   Accepted: 19978 D ...

  2. POJ 3414 Pots【bfs模拟倒水问题】

    链接: http://poj.org/problem?id=3414 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22009#probl ...

  3. POJ 1068 Parencodings【水模拟--数括号】

    链接: http://poj.org/problem?id=1068 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=27454#probl ...

  4. [ACM_模拟] POJ1068 Parencodings (两种括号编码转化 规律 模拟)

    Description Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encoded in two diff ...

  5. POJ 1027 The Same Game(模拟)

    题目链接 题意 : 一个10×15的格子,有三种颜色的球,颜色相同且在同一片内的球叫做cluster(具体解释就是,两个球颜色相同且一个球可以通过上下左右到达另一个球,则这两个球属于同一个cluste ...

  6. POJ 3078 - Shuffle'm Up - [模拟题]

    题目链接:http://poj.org/problem?id=3087 Description A common pastime for poker players at a poker table ...

  7. poj 3087 Shuffle'm Up (模拟过程)

    Description A common pastime for poker players at a poker table is to shuffle stacks of chips. Shuff ...

  8. POJ 1035 Spell checker (模拟)

    题目链接 Description You, as a member of a development team for a new spell checking program, are to wri ...

  9. poj 2632 Crashing Robots(模拟)

    链接:poj 2632 题意:在n*m的房间有num个机器,它们的坐标和方向已知,现给定一些指令及机器k运行的次数, L代表机器方向向左旋转90°,R代表机器方向向右旋转90°,F表示前进,每次前进一 ...

随机推荐

  1. centos7.x/RedHat7.x重命名网卡名称

    从51CTO博客迁移出来几篇博文. 在CentOS7.x或RedHat7.x上,网卡命名规则变成了默认,既自动基于固件.拓扑结构和位置信息来确定.这样一来虽然有好处,但也会影响操作,因为新的命名规则比 ...

  2. C# 根据包含文件的路径和文件的名称的字符串获取文件名称的几种方法

    C# 截取带路径的文件名字,扩展名,等等 的几种方法 C#对磁盘IO操作的时候,经常会用到这些,路径,文件,文件名字,文件扩展名. 之前,经常用切割字符串来实现, 可是经常会弄错. 尤其是启始位置,多 ...

  3. maven中添加servlet、jsp依赖

    或者在eclipse中,右键项目名称->Maven->Add Dependency->输入servlet,会自动找到最新的版本(记得联网哦),如图:

  4. 《机器学习实战》学习笔记——第2章 KNN

    一. KNN原理: 1. 有监督的学习 根据已知事例及其类标,对新的实例按照离他最近的K的邻居中出现频率最高的类别进行分类.伪代码如下: 1)计算已知类别数据集中的点与当前点之间的距离 2)按照距离从 ...

  5. HTML、CSS小知识--兼容IE的下拉选择框select

    HTML <div class="s_h_ie"> <select id="Select1" disabled="disabled& ...

  6. fragment 碎片整理

    activity_m1.xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xm ...

  7. 利用fiddler模拟发送json数据的post请求

    fiddler是调试利器,有许多好用的功能,这里简单的介绍一下利用fiddler模拟发送post请求的例子 先简单介绍一下失败的例子,最后给出正确的方法

  8. c# 集合适配器

    using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sy ...

  9. 获取当前html标签自定义属性的值

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...

  10. php使用openssl来实现RSA(非对称加密)

    使用非对称加密主要是借助openssl的公钥和私钥,用公钥加密私钥解密,或者私钥加密公钥解密. 1.安装openssl和PHP的openssl扩展 2.生成私钥:openssl genrsa 用于生成 ...