• 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;
    }
    
  • 相关阅读:
    第二阶段冲刺(三)
    第二阶段冲刺(二)
    第二阶段冲刺(一)
    阿里云体验:安装jdk
    知识储备
    wcf服务编程(二)
    wcf服务编程(一)
    操作xml练习
    操作文件简单的方法
    【mongoDB】学习笔记_02
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10514348.html
Copyright © 2020-2023  润新知