zoukankan      html  css  js  c++  java
  • uoj#344. 【清华集训2017】我的生命已如风中残烛(计算几何)

    题面

    传送门

    题解

    orzxyx

    首先我们发现,一个点如果被到达大于一次,那么这个点肯定在一个环上。所以在不考虑环的情况下每个点只会被到达一次,那么我们就可以直接暴力了

    简单来说,我们对每个点(i)预处理一下(to[i][from]),表示如果有一条绳子从(from)绕到(i),那么绕上(i)之后这条绳子对应的下一个点是哪个(假设绳子无限长)。这个可以通过对所有点按极角排序之后直接预处理出来

    接下来考虑环,我们可以用类似取模的手段,找到一个环之后把整圈直接跑掉,剩下的继续暴力

    建议看代码比较好理解

    //minamoto
    #include<bits/stdc++.h>
    #define R register
    #define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
    #define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
    #define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
    using namespace std;
    char buf[1<<21],*p1=buf,*p2=buf;
    inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
    int read(){
        R int res,f=1;R char ch;
        while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
        for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
        return res*f;
    }
    const int N=2005;const double Pi=acos(-1.0),eps=1e-8;
    struct node{
    	int x,y;
    	node(){}
    	node(R int xx,R int yy):x(xx),y(yy){}
    	inline node operator -(const node &b)const{return node(x-b.x,y-b.y);}
    	inline double norm(){return sqrt(1ll*x*x+1ll*y*y);}
    	inline double PA(){return atan2(y,x);}
    }p[N],s,t;
    struct qwq{
    	int pos;double dis,alp;
    	qwq(){}
    	qwq(R int P,R double D,R double A):pos(P),dis(D),alp(A){}
    	inline bool operator <(const qwq &b)const{return fabs(alp-b.alp)>eps?alp<b.alp:dis<b.dis;}
    }a[N][N];
    int n,m,to[N][N];double len;
    int solve(int pos,int from,double len){
    	if(from==n+1){
    		double res=(p[pos]-s).PA()+4*Pi;
    		fp(i,1,3*n-3)
    			if(a[pos][i].alp<res-eps&&a[pos][i].dis<len)return 1+solve(a[pos][i].pos,pos,len-a[pos][i].dis);
    		return 0;
    	}
    	int ans=0,top=0,nxt;
    	static int st[N],vis[N];
    	fp(i,1,n)vis[i]=0;
    	st[++top]=pos;
    	while(!vis[pos]){
    		vis[pos]=top,nxt=0;
    		fp(i,to[pos][from],3*n-3)
    			if(a[pos][i].dis<len){
    				++ans,nxt=a[pos][i].pos,len-=a[pos][i].dis;
    				break;
    			}
    		if(!nxt)return ans;
    		from=pos,pos=nxt,st[++top]=pos;
    	}
    	int bg=vis[pos];
    	fp(T,bg,top-1){
    		nxt=0;
    		fp(i,to[pos][from],3*n-3)
    			if(a[pos][i].dis<len){
    				++ans,nxt=a[pos][i].pos,len-=a[pos][i].dis;
    				break;
    			}
    		if(!nxt)return ans;
    		from=pos,pos=nxt;
    		if(pos!=st[T+1])return ans+solve(pos,from,len);
    	}
    	double res=0;
    	fp(i,bg,top-1)res+=(p[st[i]]-p[st[i+1]]).norm();
    	int q=len/res;
    	len-=q*res,ans+=(top-vis[pos])*q;
    	return ans+solve(st[top],st[top-1],len);
    }
    int main(){
    //	freopen("testdata.in","r",stdin);
    	for(int T=read();T;--T){
    		n=read(),m=read();
    		fp(i,1,n)p[i].x=read(),p[i].y=read();
    		for(R int i=1;i<=n;++i){
    			int top=0;
    			fp(j,1,i-1)a[i][++top]=qwq(j,(p[j]-p[i]).norm(),(p[j]-p[i]).PA());
    			fp(j,i+1,n)a[i][++top]=qwq(j,(p[j]-p[i]).norm(),(p[j]-p[i]).PA());
    			sort(a[i]+1,a[i]+1+top);
    			fp(j,1,top){
    				a[i][j+top]=a[i][j+(top<<1)]=a[i][j];
    				a[i][j+top].alp+=2*Pi,a[i][j+(top<<1)].alp+=4*Pi;
    			}
    			reverse(a[i]+1,a[i]+top*3+1);
    			for(R int j=1,pos=1;j<=top;++j){
    				while(a[i][j].alp-a[i][pos].alp<=Pi-eps)++pos;
    				to[i][a[i][j].pos]=pos;
    			}
    		}
    		while(m--){
    			s.x=read(),s.y=read(),t.x=read(),t.y=read(),len=read();
    			static qwq st[N];int top=0;
    			st[++top]=qwq(n+1,len,(t-s).PA());
    			fp(i,1,n)st[++top]=qwq(i,(p[i]-s).norm(),(p[i]-s).PA());
    			sort(st+1,st+1+top);
    			fp(i,1,top)st[i+top]=st[i],st[i+top].alp+=2*Pi;
    			reverse(st+1,st+1+(top<<1));
    			fp(i,1,top)if(st[i].pos==n+1){
    				int pos=0;
    				fp(k,i+1,i+top)if(st[k].dis<len-eps){pos=k;break;}
    				printf("%d
    ",!pos?1:2+solve(st[pos].pos,n+1,len-st[pos].dis));
    				break;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    poj 3068 Bridge Across Islands
    XidianOJ 1086 Flappy v8
    XidianOJ 1036 分配宝藏
    XidianOJ 1090 爬树的V8
    XidianOJ 1088 AK后的V8
    XidianOJ 1062 Black King Bar
    XidianOJ 1091 看Dota视频的V8
    XidianOJ 1098 突击数论前的xry111
    XidianOJ 1019 自然数的秘密
    XidianOJ 1109 Too Naive
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10514348.html
Copyright © 2011-2022 走看看