Problem:
Problem J:
Secret Operation
Mary Ice is a member of a spy group. She is about to carry out a secret operation with her colleague.
She has got into a target place just now, but unfortunately the colleague has not reached there yet. She
needs to hide from her enemy George Water until the colleague comes. Mary may want to make herself
appear in George’s sight as short as possible, so she will give less chance for George to find her.
You are requested to write a program that calculates the time Mary is in George’s sight before her colleague arrives, given the information about moves of Mary and George as well as obstacles blocking their
sight.
Read the Input section for the details of the situation.
Input
The input consists of multiple datasets. Each dataset has the following format:
Time R
L
MaryX
1
MaryY
1
MaryT
1
MaryX
2
MaryY
2
MaryT
2
...
MaryX
L
MaryY
L
MaryT
L
M
GeorgeX
1
GeorgeY
1
GeorgeT
1
GeorgeX
2
GeorgeY
2
GeorgeT
2
...
GeorgeX
M
GeorgeY
M
GeorgeT
M
N
BlockSX
1
BlockSY
1
BlockTX
1
BlockTY
1
BlockSX
2
BlockSY
2
BlockTX
2
BlockTY
2
...
BlockSX
N
BlockSY
N
BlockTX
N
BlockTY
N
The first line contains two integers. Time (0 ≤
Time
≤ 100) is the time Mary's colleague reaches the
place.
R
(0 <
R
< 30000) is the distance George can see - he has a sight of this distance and of 45
degrees left and right from the direction he is moving. In other words, Mary is found by him if and only
if she is within this distance from him and in the direction different by not greater than 45 degrees from
his moving direction and there is no obstacles between them.
The description of Mary's move follows. Mary moves from (
MaryX
i
,
MaryY
i
) to (
MaryX
i
+1
,
MaryY
i
+1
)
straight and at a constant speed during the time between
MaryT
i
and
MaryT
i
+1
, for each 1 ≤
i
≤
L
- 1.
The following constraints apply: 2 ≤
L
≤ 20,
MaryT
1
= 0 and
MaryT
L
=
Time
, and
MaryT
i
<
MaryT
i
+1
for any 1 ≤
i
≤
L
- 1.
The description of George's move is given in the same way with the same constraints, following Mary's.
In addition, (
GeorgeX
j
,
GeorgeY
j
) and (
GeorgeX
j
+1
,
GeorgeY
j
+1
) do not coincide for any 1 ≤
j
≤
M
- 1. In other words, George is always moving in some direction.
Finally, there comes the information of the obstacles. Each obstacle has a rectangular shape occupying
(
BlockSX
k
,
BlockSY
k
) to (
BlockTX
k
,
BlockTY
k
). No obstacle touches or crosses with another. The number of obstacles ranges from 0 to 20 inclusive.
All the coordinates are integers not greater than 10000 in their absolute values. You may assume that, if
the coordinates of Mary's and George's moves would be changed within the distance of 10
-6
, the solution would be changed by not greater than 10
-6
.
The last dataset is followed by a line containing two zeros. This line is not a part of any dataset and should not be processed.
Output
For each dataset, print the calculated time in a line. The time may be printed with any number of digits after the decimal
point, but should be accurate to 10

...(truncated)

Submitted solutions:

code_snippet: bool debug=false;
#include <stdio.h>
#include <utility>
#include <vector>
#include <math.h>
using namespace std;
typedef pair<double,double> pd;
typedef pair<pd,double> ppdd;
typedef pair<pd,pd> ppdpd;
#define F first
#define S second
#define PB push_back
const double N=0.00005;
const double eps=1e-9;
double dist(pd a,pd b){
	double x=a.F-b.F,y=a.S-b.S;
	return sqrt(x*x+y*y);
}
double myabs(double n){return n>=0?n:-n;}
int pn(double n){return myabs(n)<eps?0:n>0?1:-1;}
bool between(pd a,pd b,pd c){
	if((-eps<=b.F-a.F&&-eps<=c.F-b.F)||(a.F-b.F>=-eps&&b.F-c.F>=-eps))if((-eps<=b.S-a.S&&-eps<=c.S-b.S)||(a.S-b.S>=-eps&&b.S-c.S>=-eps))return true;
	return false;
}
bool intersect(pd x1,pd x2,pd y1,pd y2){
	if(debug)printf("x1=(%.3lf,%.3lf) x2=(%.3lf,%.3lf) y1=(%.3lf,%.3lf) y2=(%.3lf,%.3lf)\n",x1.F,x1.S,x2.F,x2.S,y1.F,y1.S,y2.F,y2.S); 
	double A1=x1.S-x2.S,B1=x2.F-x1.F,A2=y1.S-y2.S,B2=y2.F-y1.F,C1,C2;
	C1=A1*x1.F+B1*x1.S;
	C2=A2*y1.F+B2*y1.S;
	if(myabs(A1*B2-A2*B1)<eps){
		if(myabs(A2*x1.F+B2*x1.S-C2)<eps)return between(x1,y1,x2)|between(y1,x1,y2);
		else return false;
	}
	else{
		double x=(C1*B2-C2*B1),y=(A1*C2-C1*A2),det=(A1*B2-A2*B1);
		pd p={x/det,y/det};
		return between(x1,p,x2)&between(y1,p,y2);
	}
}
bool cansee(double range,vector<ppdpd> &v,ppdd a0,ppdd a1,ppdd b0,ppdd b1,double now){
	pd apos={(a1.F.F-a0.F.F)*(now-a0.S)/(a1.S-a0.S)+a0.F.F,(a1.F.S-a0.F.S)*(now-a0.S)/(a1.S-a0.S)+a0.F.S},bpos={(b1.F.F-b0.F.F)*(now-b0.S)/(b1.S-b0.S)+b0.F.F,(b1.F.S-b0.F.S)*(now-b0.S)/(b1.S-b0.S)+b0.F.S};
	if(debug)printf("apos=(%.3lf,%.3lf) bpos=(%.3lf,%.3lf)\n",apos.F,apos.S,bpos.F,bpos.S);
	if(dist(apos,bpos)>range){
		if(debug)printf("too far\n");
		return false;
	}
	for(ppdpd i:v)if(intersect(i.F,i.S,apos,bpos)){
		if(debug)printf("intersect\n");
		return false;
	}
	b1.F={(b1.F.F-b0.F.F)+bpos.F,(b1.F.S-b0.F.S)+bpos.S};
	double Al,Bl,Cl,Ar,Br,Cr,A=b0.F.S-b1.F.S,B=b1.F.F-b0.F.F,C,rA,rB,rC;
	int l,r;
	pd lpos,rpos;
	C=A*b0.F.F+B*b0.F.S;
	rA=B;
	rB=-A;
	rC=rA*b1.F.F+rB*b1.F.S;
	lpos={b1.F.F+bpos.S-b1.F.S,b1.F.S+b1.F.F-bpos.F};
	rpos={b1.F.F-bpos.S+b1.F.S,b1.F.S-b1.F.F+bpos.F};
	Al=lpos.S-bpos.S,Ar=rpos.S-bpos.S;
	Bl=bpos.F-lpos.F,Br=bpos.F-rpos.F;
	Cl=Al*bpos.F+Bl*bpos.S;
	Cr=Ar*bpos.F+Br*bpos.S;
	l=pn(Al*apos.F+Bl*apos.S-Cl);
	r=pn(Ar*apos.F+Br*apos.S-Cr);
	if(l==0||l==pn(Al*b1.F.F+Bl*b1.F.S-Cl))if(r==0||r==pn(Ar*b1.F.F+Br*b1.F.S-Cr)){
		if(debug)printf("ok::l=%d ansl=%d r=%d ansr=%d\n",l,pn(Al*b1.F.F+Bl*b1.F.S-Cl),r,pn(Ar*b1.F.F+Br*b1.F.S-Cr));
		return true;
	}
	if(debug)printf("no::l=%d ansl=%d r=%d ansr=%d\n",l,pn(Al*b1.F.F+Bl*b1.F.S-Cl),r,pn(Ar*b1.F.F+Br*b1.F.S-Cr));
	return false;
}
void solve(double t,double r){
	int l,m,n,lpos=0,rpos=0;
	double ans=0,now=N,last=0;
	ppdd temp;
	ppdpd tt;
	vector<ppdd> a,b;
	vector<ppdpd> wall;
	scanf("%d",&l);
	for(int i=0;i<l;i++){
		scanf("%lf%lf%lf",&temp.F.F,&temp.F.S,&temp.S);
		a.PB(temp);
	}
	scanf("%d",&m);
	for(int i=0;i<m;i++){
		scanf("%lf%lf%lf",&temp.F.F,&temp.F.S,&temp.S);
		b.PB(temp);
	}
	scanf("%d",&n);
	for(int i=0;i<n;i++){
		scanf("%lf%lf%lf%lf",&tt.F.F,&tt.F.S,&tt.S.F,&tt.S.S);
		wall.PB({{tt.F.F,tt.F.S},{tt.F.F,tt.S.S}});
		wall.PB({{tt.F.F,tt.S.S},{tt.S.F,tt.S.S}});
		wall.PB({{tt.F.F,tt.F.S},{tt.S.F,tt.F.S}});
		wall.PB({{tt.S.F,tt.F.S},{tt.S.F,tt.S.S}});
	}
	while(now<t){
		while(lpos+2<l&&a[lpos+1].S<now)lpos++;
		while(rpos+2<m&&b[rpos+1].S<now)rpos++;
		if(!cansee(r,wall,a[lpos],a[lpos+1],b[rpos],b[rpos+1],now)){
			ans+=now-last-N;
			if(debug)printf("last=%lf now=%lf ans=%lf\n",last,now,ans);
			last=now;
		}
		now+=N;
	}
	ans+=now-last-N;
	printf("%.20lf\n",(double)ans);
}
int main(){
	int t,r,cnt=0;
	while(true){
		scanf("%d%d",&t,&r);
		if(t==0&&r==0)return 0;
		solve(t,r);
	}
}
accuracy: 1
time_ms: 2630
memory_kb: 2732
final_rank: 1

code_snippet: #include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <unordered_map>
#include <iterator>
#include <assert.h>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define REPS(i,x) for(int i=1;i<=(int)(x);i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RREPS(i,x) for(int i=((int)(x));i>0;i--)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) (container).begin(), (container).end()
#define RALL(container) (container).rbegin(), (container).rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}
template<class S, class T> pair<S,T> operator+(const pair<S,T> &s, const pair<S,T> &t){ return pair<S,T>(s.first+t.first, s.second+t.second);}
template<class S, class T> pair<S,T> operator-(const pair<S,T> &s, const pair<S,T> &t){ return pair<S,T>(s.first-t.first, s.second-t.second);}

namespace geom{
#define X real()
#define Y imag()
#define at(i) ((*this)[i])
#define SELF (*this)
	enum {TRUE = 1, FALSE = 0, BORDER = -1};
	typedef int BOOL;
	typedef double R;
	const R INF = 1e8;
	R EPS = 1e-6;
	const R PI = 3.1415926535897932384626;
	inline int sig(const R &x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
	inline BOOL less(const R &x, const R &y) {return sig(x-y) ? x < y : BORDER;}
	typedef complex<R> P;
	inline R norm(const P &p){return p.X*p.X+p.Y*p.Y;}
	inline R inp(const P& a, const P& b){return (conj(a)*b).X;}
	inline R outp(const P& a, const P& b){return (conj(a)*b).Y;}
	inline P unit(const P& p){return p/abs(p);}
	inline P proj(const P &s, const P &t){return t*inp(s, t)/norm(t);}
	inline int ccw(const P &s, const P &t, const P &p, int adv=0){
		int res = sig(outp(t-s, p-s));
		if(res || !adv) return res;
		if(sig(inp(t-s, p-s)) < 0) return -2;	// p-s-t
		if(sig(inp(s-t, p-t)) < 0) return 2;	// s-t-p
		return 0;								// s-p-t
	}
	
	
	struct L : public vector<P>{	// line
		L(const P &p1, const P &p2){this->push_back(p1);this->push_back(p2);}
		L(){}
		P dir()const {return at(1) - at(0);}
		BOOL online(const P &p)const {return !sig(outp(p-at(0), dir()));}
	};
	struct S : public L{	// segment
		S(const P &p1, const P &p2):L(p1, p2){}
		S(){}
		BOOL online(const P &p)const {
			if(!sig(norm(p - at(0))) || !sig(norm(p - at(1)))) return BORDER;
			// 座標の二乗とEPSの差が大きすぎないように注意
			return !sig(outp(p-at(0), dir())) && inp(p-at(0), dir()) > EPS && inp(p-at(1), -dir()) > -EPS;
			//return !sig(abs(at(0)-p) + abs(at(1) - p) - abs(at(0) - at(1)));
		}
	};
	BOOL intersect(const S &s, const S &t){
		const int p = ccw(t[0], t[1], s[0], 1) * ccw(t[0], t[1], s[1], 1);
		const int q = ccw(s[0], s[1], t[0], 1) * ccw(s[0], s[1], t[1], 1);
		return (p>0||q>0) ? FALSE : (!p||!q) ? BORDER : TRUE;
	}

#undef SELF
#undef at
}

using namespace geom;

namespace std{
	bool operator<(const P &a, const P &b){return sig(a.X-b.X) ? a.X < b.X : a.Y+EPS < b.Y;}
	bool operator==(const P &a, const P &b){return abs(a-b) < EPS;}
	istream& operator>>(istream &is, P &p){R x,y;is>>x>>y;p=P(x, y);return is;}
	const R B = 500;
	const R Z = .05;
	ostream& operator<<(ostream &os, const P &c){return os << "circle("<<B+Z*(c.X)<<", "<<1000-B-Z*(c.Y)<<", 2)";}
	ostream& operator<<(ostream &os, const S &s){return os << "line("<<B+Z*(s[0].X)<<", "<<1000-B-Z*(s[0].Y)<<", "<<B+Z*(s[1].X)<<", "<<1000-B-Z*(s[1].Y)<<")";}

}

R T, range;
int n;

const R inc = 7e-5;

int main(int argc, char *argv[]){
	ios::sync_with_stdio(false);
	while(cin >> T >> range, range > EPS){
		vector<pair<P, R>> M, G;
		int L;
		cin >> L;
		REP(i, L){
			P p;
			R t;
			cin >> p >> t;
			M.emplace_back(p, t);
		}
		cin >> L;
		REP(i, L){
			P p;
			R t;
			cin >> p >> t;
			G.emplace_back(p, t);
		}
		vector<S> obs;
		cin >> L;
		REP(i, L){
			R sx, sy, tx, ty;
			cin >> sx >> sy >> tx >> ty;
			obs.emplace_back(P(sx, sy), P(sx, ty));
			obs.emplace_back(P(sx, sy), P(tx, sy));
			obs.emplace_back(P(tx, sy), P(tx, ty));
			obs.emplace_back(P(sx, ty), P(tx, ty));
		}
		int i=-1, j=-1;
		R ans = 0;
		P m = M[0].first;
		P g = G[0].first;
		P md;
		P gd;
		for(R t=0;t<T;t+=inc){
			if(M[i+1].second <= t){
				i++;
				m = M[i].first;
				md = (M[i+1].first - M[i].first);
			}
			if(G[j+1].second <= t){
				j++;
				g = G[j].first;
				gd = (G[j+1].first - G[j].first);
			}
			const P mm = m + md * ((t - M[i].second) / (M[i+1].second - M[i].second));
			const P gg = g + gd * ((t - G[j].second) / (G[j+1].second - G[j].second));
			const S s(gg, mm);
			if(norm(s.dir()) > range*range || abs(arg(gd / s.dir())) > PI*(R).25 || [&](){
				FOR(o, obs) if(intersect(s, *o)) return 1;
				return 0;
			}()) continue;
			ans += inc;
		}
		printf("%.5f\n", ans);
	}
	return 0;
}
accuracy: 1
time_ms: 5100
memory_kb: 1364
final_rank: 2

code_snippet: #include<bits/stdc++.h>

#define EQ(a,b) (abs((a)-(b)) < EPS)
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define fs first
#define sc second
#define pb push_back
#define sz size()
#define all(a) (a).begin(),(a).end()

using namespace std;
typedef double D;
typedef complex<D> P;
typedef pair<P,P> Line;
typedef vector<P> Poly;

const D EPS = 1e-8;
const D PI = acos(-1);
const D sq2 = 1.0/sqrt(2.0);

inline D dot(P x, P y){return real(conj(x)*y);}
inline D cross(P x, P y){return imag(conj(x)*y);}

int ccw(P a,P b,P c){
  b -= a;c -= a;
  if (cross(b,c)>EPS) return 1;   //counter clockwise
  if (cross(b,c)<-EPS) return -1; //clockwise
  if (dot(b, c)<-EPS) return 2;   //c--a--b on line
  if (abs(b)+EPS<abs(c)) return -2;   //a--b--c on line
  return 0;                       //on segment
}

inline bool is_cp(Line a,Line b){
  if(ccw(a.fs,a.sc,b.fs)*ccw(a.fs,a.sc,b.sc)<=0)
    if(ccw(b.fs,b.sc,a.fs)*ccw(b.fs,b.sc,a.sc)<=0)return true;
  return false;
}

int main(){
  D Time,R;
  int L,M,N;
  P pm[55], vm[55], pg[55], vg[55];
  D tm[55], tg[55];
  Poly obj[55];

  cin.tie(0);
  std::ios::sync_with_stdio(false);
  while(cin >> Time >> R){
    if(EQ(Time,0) && EQ(R,0))break;

    cin >> L;
    rep(i,L){
      D x,y;
      cin >> x >> y >> tm[i];
      pm[i] = P(x,y);
    }
    rep(i,L-1)vm[i] = (pm[i+1] - pm[i]) / (tm[i+1] - tm[i]);

    cin >> M;
    rep(i,M){
      D x,y;
      cin >> x >> y >> tg[i];
      pg[i] = P(x,y);
    }
    rep(i,M-1)vg[i] = (pg[i+1] - pg[i]) / (tg[i+1] - tg[i]);

    cin >> N;
    rep(i,N){
      D xl, yb, xr, yt;
      cin >> xl >> yb >> xr >> yt;
      if(xl > xr)swap(xl,xr);
      if(yb > yt)swap(yb,yt);

      obj[i].clear();
      obj[i].pb(P(xl,yb)); obj[i].pb(P(xr,yb));
      obj[i].pb(P(xr,yt)); obj[i].pb(P(xl,yt));
    }

    vector<D> event;

    int sm=0, sg=0;
    D hoge = 0;
    while(hoge<=Time+EPS){
      event.pb(hoge);
      hoge += 0.00005;
    }

    D ans = 0;
    sm = 0; sg = 0;
    rep(t,event.sz-1){
      D T = (event[t] + event[t+1])/2;
      if(sm<L && EQ(tm[sm+1], event[t]))sm++;
      if(sg<M && EQ(tg[sg+1], event[t]))sg++;

      //check
      bool f = true;
      P curM = P(vm[sm].real() * (T-tm[sm]) + pm[sm].real(),
		 vm[sm].imag() * (T-tm[sm]) + pm[sm].imag() );
      P curG = P(vg[sg].real() * (T-tg[sg]) + pg[sg].real(),
		 vg[sg].imag() * (T-tg[sg]) + pg[sg].imag() );

      if(abs(curM-curG) > R+EPS)f = false;
      else{
	P A = pg[sg+1]-curG, B = curM-curG;
	if(dot(A,B)/abs(A)/abs(B) +EPS < sq2)f = false;
	else{
	  Line eye = Line(curM, curG);
	  rep(i,N){
	    rep(j,obj[i].sz){
	      Line wall = Line( obj[i][j], obj[i][(j+1)%obj[i].sz] );
	      if(is_cp(eye, wall)){
		f = false; break;
	      }
	      if(!f)break;
	    }
	  }
	}
      }

      if(f)ans += event[t+1]-event[t];
    }

    cout << fixed << setprecision(12) << ans << endl;
  }
}
accuracy: 1
time_ms: 3200
memory_kb: 33196
final_rank: 3