SCOI2003BZOJ1092蜘蛛难题
Posted Kaiser
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SCOI2003BZOJ1092蜘蛛难题相关的知识,希望对你有一定的参考价值。
有一堆管道,还有一个蜘蛛Willy,如下图所示。所有管道的是上端开口,下端封底,直径都是1cm,连接两个管道的连接容量无限,但体积可以忽略不计。
在第一个管道上方有一个水源,从中有水不断往下流,速度为每秒0.25? cm3。由于管道横截面积为0.25? cm3,所以单给一个管道注水时水面每秒上升1cm。根据物理知识,在前2秒中,水注如左边的管道底部,第3~5秒时注入右边的管道,第6~9秒同时注入两个管道(虽然流量不变,但是由于同时给两个管道注水,因此水面上升的速度仅为每秒0.5cm),接触到蜘蛛。 给出管道和管道之间连接的位置,以及蜘蛛Willy的位置,求水面接触到Willy的时间。假设蜘蛛的实际位置比给出的略高一点,因此如果蜘蛛在左边管道的n=4的位置,答案应该是5秒。因为前两秒后水面虽然看起来接触到了Willy,但实际上比Willy略低一点。
Input
所有位置都用有序数对(x, y)表示,其中y坐标从上到下逐渐增大;x坐标从左到右逐渐增大,因此左上角的坐标为(0,0),其他所有坐标值为0到100之间的整数。输入第一行为一个整数p(1<=p<=20),表示管道的数目;以下p行,每行用x, y, h三个整数描述一根管道。(x,y)为管道左上角坐标;h为管道高度(1<=h<=20)。以下一行为一个整数L(0<=L<=50),为连接的个数。以下L行每行用三个整数x, y, d描述一个连接,(x,y)为左端点的坐标,d为连接的长度(1<=d<=20)。最后一行为两个整数a, b,表示Willy在管道a的y坐标为b的位置。管道按照在文件中出现的顺序编号为1,2,3…p 以下为一些假设:? 水源总是在第一根管道的正上方? 连接不会穿越管道? 任意两个连接的y坐标都不相同? 任意两个管道的左上角的x坐标都不相同? 任意连接的两个端点都在管道上(不会出现悬空的情形)
Output
仅一个整数,为水面接触到Willy的时间。如果水面无法接触到Willy,输出-1。
Sample Input
2 2 0 6 5 1 6 1 3 4 2 2 2
Sample Output
9
Hint
该样例对应题目中的例子。
题解:这道题目就是模拟吧,每次搞到当前的平面,然后联通的就直接搞出去,
然后计算就可以了,细节考虑应该会比较多。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cmath> 5 #include<algorithm> 6 #define N 30 7 #define M 110 8 9 using namespace std; 10 11 int n,m,S,T; 12 int cnt,head[N],next[M*2],rea[M*2],val[M*2]; 13 struct Node 14 { 15 int x,y,h,v; 16 }a[N]; 17 18 void add(int u,int v,int fee) 19 { 20 cnt++; 21 next[cnt]=head[u]; 22 head[u]=cnt; 23 rea[cnt]=v; 24 val[cnt]=fee; 25 } 26 int find(int x) 27 { 28 for (int i=1;i<=n;i++) 29 if (a[i].x==x) return i; 30 return 0; 31 } 32 int main() 33 { 34 memset(head,-1,sizeof(head)); 35 int ans=0; 36 scanf("%d",&n); 37 for (int i=1;i<=n;i++) 38 scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].h); 39 for (int i=1;i<=n;i++) 40 a[i].h+=a[i].y; 41 a[1].v=1; 42 scanf("%d",&m); 43 int x,y,len; 44 for (int i=1;i<=m;i++) 45 { 46 scanf("%d%d%d",&x,&y,&len); 47 int st=find(x-1),ed=find(x+len); 48 add(st,ed,y),add(ed,st,y); 49 } 50 scanf("%d%d",&S,&T); 51 while (1) 52 { 53 x=1; 54 while (x) 55 { 56 x=0; 57 for (int i=1;i<=n;i++) 58 if (a[i].v) 59 for (int j=head[i];j!=-1;j=next[j]) 60 { 61 int v=rea[j],fee=val[j]; 62 if (a[i].h<=fee&&!a[v].v) a[v].v=x=1; 63 } 64 } 65 int mx=-1; 66 for (int i=1;i<=n;i++) 67 if (a[i].v) mx=max(mx,a[i].h); 68 if (a[S].v&&mx==T) 69 { 70 printf("%d\n",ans); 71 return 0; 72 } 73 for (int i=1;i<=n;i++) 74 if (a[i].v&&a[i].h==a[i].y&&mx==a[i].y) 75 { 76 printf("-1\n"); 77 return 0; 78 } 79 for (int i=1;i<=n;i++) 80 if (a[i].v&&a[i].h==mx) 81 { 82 a[i].h--; 83 ans++; 84 } 85 } 86 }
以上是关于SCOI2003BZOJ1092蜘蛛难题的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1091([SCOI2003]分割多边形-分割直线)