Gym - 101490F:Endless Turning (几何模拟)
题目链接:http://codeforces.com/gym/101490/attachments
SOLUTION:
其实就是一个模拟,但是难点是如何操作
CODE:
#include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; const int maxn=200010; const double eps=1e-8; struct point{ double x,y; point(){} point(double xx,double yy):x(xx),y(yy){} }; struct line{ point s,t; point p; line(){} line(point ss,point pp):s(ss),p(pp){} }; double det(point a,point b){ return a.x*b.y-a.y*b.x; } double dot(point a,point b){ return a.x*b.x+a.y*b.y; } point operator *(point a,double x){ return point(a.x*x,a.y*x);} point operator +(point a,point b){ return point(a.x+b.x,a.y+b.y);} point operator -(point a,point b){ return point(a.x-b.x,a.y-b.y);} line road[maxn]; string name[maxn]; ll N;int R,Now; point S; line st; point llintersect(line a,line b) { point w=a.s-b.s; double t=det(b.p,w)/det(a.p,b.p); return a.s+a.p*t; } bool Online(point p,line L) { return fabs(det(p-L.t,p-L.s))<eps; } bool parl(point p,point q){ return fabs(det(p,q))<eps; } void Change(int i) { swap(road[i].s,road[i].t); road[i].p=road[i].t-road[i].s; } void find() { rep(i,1,R){ if(Online(S,road[i])) { if(dot(point(1,0),road[i].p)<eps) Change(i); st=road[i]; Now=i; return ; } } } int tot,h[maxn],vis[maxn]; point p[maxn]; int main() { scanf("%d%lld%lf%lf",&R,&N,&S.x,&S.y); rep(i,1,R) { cin>>name[i]; scanf("%lf%lf%lf%lf",&road[i].s.x,&road[i].s.y,&road[i].t.x,&road[i].t.y); road[i].p=road[i].t-road[i].s; } if(R==1||N==0){ cout<<name[1]<<endl; return 0; } int C=0; find(); h[0]=Now; vis[Now]=1; p[0]=S; while(1){ int t=0; point tp; rep(i,1,R){ if(i==Now) continue; if(parl(st.p,road[i].p)) continue;//垂直 point o=llintersect(st,road[i]); if(dot(o-p[tot],st.p)<=0) continue;//反向 if(fabs(o.x-p[tot].x)<=eps&&fabs(o.y-p[tot].y)<=eps) continue;// 相同的点 if(det(st.p,road[i].p)>eps) Change(i); // 调向 if(t==0||dot(o-p[tot],o-p[tot])<dot(tp-p[tot],tp-p[tot])){ t=i; tp=o; } } if(t==0||tot==N){ cout<<name[Now]<<endl; return 0; } Now=t; st=road[t]; h[++tot]=t; p[tot]=tp;//+st.p*eps; if(vis[Now]) { break;} vis[Now]=1; if(tot==N){ cout<<name[Now]<<endl; return 0; } } cout<<name[h[N%tot]]<<endl; return 0; }