#include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <algorithm>
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
using namespace std;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
#define eps 1e-4
#define PI 3.1415927
#define G 9.18
#define N 15
#define zero(x) (((x)>0?(x):-(x))<eps)
#define _sign(x) ((x)>eps?1:((x)<-eps?2:0))
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) struct point {
double x, y;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) void out() {
printf("%lf %lf\n", x, y);
}
};
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) struct dam_borad {
double H, k;
int len, type;
point cor[N];
}dam[N];
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
double vx, vy, iniH, totTime;
int n, cases;
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) double xmult(point p1, point p2, point p0) {
return (p1.x - p0.x)* (p2.y-p0.y) - (p2.x - p0.x) * (p1.y - p0.y);
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) int dots_inline(point p1, point p2, point p3) {
return zero(xmult(p1, p2, p3));
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) int same_side(point p1, point p2, point l1, point l2) {
return xmult(l1, p1, l2) * xmult(l1, p2, l2) > eps;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) int dot_online_in(point p, point l1, point l2) {
return zero(xmult(p, l1, l2)) && (l1.x-p.x) * (l2.x-p.x) < eps &&
(l1.y-p.y) * (l2.y-p.y) < eps;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) int intersect_in(point u1, point u2, point v1, point v2) {
if( !dots_inline(u1, u2, v1) || !dots_inline(u1, u2, v2))
return !same_side(u1, u2, v1, v2) && !same_side(v1,v2, u1, u2);
return dot_online_in(u1,v1, v2) || dot_online_in(u2,v1, v2) || dot_online_in(v1,u1, u2)
|| dot_online_in(v2,u1, u2);
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) point intersection(point u1, point u2, point v1, point v2) {
point ret = u1;
double t = (( u1.x - v1.x) * (v1.y - v2.y) - (u1.y - v1.y) * (v1.x - v2.x)) /
(( u1.x - u2.x) * (v1.y - v2.y) - (u1.y - u2.y) * (v1.x - v2.x));
ret.x += (u2.x - u1.x) * t;
ret.y += (u2.y - u1.y) * t;
return ret;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) int inside_polygon(point q, int n) {
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) int i , s[3] = {1, 1, 1};
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) for(i = 0; i < dam[n].len && s[1] | s[2]; i ++) {
s[ _sign(xmult(dam[n].cor[i+1], q, dam[n].cor[i]))] = 0;
}
return s[1]|s[2];
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) int cmp(dam_borad a, dam_borad b) {
return b.H - a.H < -eps;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) void read() {
scanf("%lf %lf %lf", &vx, &vy, &iniH);
scanf("%d", &n);
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) for(int i = 0; i < n; i ++) {
scanf("%lf", &dam[i].H);
scanf("%d", &dam[i].len);
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) for(int j = 0; j < dam[i].len; j ++) {
scanf("%lf %lf", &dam[i].cor[j].x, &dam[i].cor[j].y);
}
dam[i].cor[dam[i].len] = dam[i].cor[0];
scanf("%d", &dam[i].type);
scanf("%lf", &dam[i].k);
}
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) void init() {
sort(dam, dam + n, cmp);
totTime = 0;
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) void drop() {
int damNum = 0;
point now, nowV;
double nowH;
now.x = now.y = 0;
nowV.x = vx;
nowV.y = vy;
nowH = iniH;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if(nowH < -eps) {
totTime = -1;
return;
}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) while(damNum < n) {
if( dam[damNum].H < eps) break;
double detH = nowH - dam[damNum].H;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if(detH < -eps) {
damNum ++;
continue;
}
double time = sqrt(2 * detH / G);
point nowp, newp, end;
newp.x = now.x + time * nowV.x;
newp.y = now.y + time * nowV.y;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if( inside_polygon(newp, damNum) ) {
nowH = dam[damNum].H;
totTime += time;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if( dam[damNum].type == 0 ) {
double tp1 = cos(dam[damNum].k), tp2 = sin(dam[damNum].k);
double tempvx = nowV.x * tp1 - nowV.y * tp2;
double tempvy = nowV.x * tp2 + nowV.y * tp1;
nowV.x = tempvx;
nowV.y = tempvy;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) } else if( dam[damNum].type == 1) {
nowV.x = dam[damNum].k;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) } else if( dam[damNum].type == 2) {
nowV.y = dam[damNum].k;
}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if(fabs(nowV.x) < eps && fabs(nowV.y) < eps) {
totTime = -1;
return;
}
end.x = newp.x + 1000 * nowV.x;
end.y = newp.y + 1000 * nowV.y;
now = newp;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) for(int i = 0; i < dam[damNum].len; i ++) {
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if( dot_online_in(newp, dam[damNum].cor[i], dam[damNum].cor[i + 1]) ) {
point tp;
tp.x = newp.x + nowV.x; tp.y = newp.y + nowV.y;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if( dot_online_in(tp, dam[damNum].cor[i], dam[damNum].cor[i + 1]) ) {
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if( dot_online_in(dam[damNum].cor[i], newp, end) ) {
now = dam[damNum].cor[i]; break;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) } else {
now = dam[damNum].cor[i+1]; break;
}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) } else {
continue;
}
}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if( intersect_in(newp, end, dam[damNum].cor[i], dam[damNum].cor[i + 1]) ) {
now = intersection(newp, end, dam[damNum].cor[i], dam[damNum].cor[i + 1]);
break;
}
}
if( fabs(nowV.x) < eps ) totTime += fabs(now.y - newp.y) / fabs(nowV.y);
else totTime += fabs(now.x - newp.x) / fabs(nowV.x);
}
damNum ++;
}
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) if(nowH > 0) {
totTime += sqrt(2 * nowH / G);
}
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) void out() {
printf("Case %d: ", cases++);
if(totTime > -eps)
printf("%.2lf\n", totTime);
else printf("Forever!\n");
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif) int main() {
int t;
scanf("%d", &t);
cases = 1;
![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif) while(t --) {
read();
init();
drop();
out();
}
}
![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
|