zoukankan      html  css  js  c++  java
  • 【BZOJ5328】【SDOI2018】—物理实验(扫描线+双指针)

    传送门

    题解:

    #include<cstdio>
    int main(){int t;cin>>t;while(t--)puts("nan");}
    

    真的AA了……
    有个0ms0ms就是我


    说正解

    先把导轨转到xx轴上
    发现这时候xx长度相同的时候覆盖的长度和线段斜率是成正比的
    于是我们可以把斜率当做价值

    同时可以发现同一xx轴只需要维护yy最小的一段
    可以用扫描线来维护所有线段,用setset维护一下就可以了

    注意开long doublelong double

    #include<bits/stdc++.h>
    using namespace std;
    #define double long double
    inline int read(){
    	char ch=getchar();
    	int res=0,f=1;
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=getchar();
    	return res*f;
    }
    const int N=100005;
    int n,m,q[N];
    double x[N][2],y[N][2],sec[N],val[N],p[N],X0,Y0,X1,Y1,len;
    inline bool comp(int a,int b){
    	return ((a>0)?x[a][0]:x[-a][1])<((b>0)?x[b][0]:x[-b][1]);
    }
    struct line{
    	int u;
    	line(int _u=0):u(_u){}
    	inline friend bool operator <(const line &a,const line &b){
    		if(a.u==b.u)return false;
    		double ya=(y[a.u][0]-y[a.u][1])/(x[a.u][0]-x[a.u][1])*(X0-x[a.u][0])+y[a.u][0];
    		double yb=(y[b.u][0]-y[b.u][1])/(x[b.u][0]-x[b.u][1])*(X0-x[b.u][0])+y[b.u][0];
    		return abs(ya)<abs(yb);
    	}
    };
    set<line> up,down;
    inline double P(double x){
    	return x*x;
    }
    inline void solve(){
    	double dx=X1-X0,dy=Y1-Y0,L=sqrt(P(dx)+P(dy)),si=dy/L,co=dx/L;
    	for(int i=1;i<=n;i++){
            x[i][0]-=X0,x[i][1]-=X0,y[i][0]-=Y0,y[i][1]-=Y0;
            double t1,t2,t3,t4;
            t1=x[i][0]*co+y[i][0]*si,t2=y[i][0]*co-x[i][0]*si;
            t3=x[i][1]*co+y[i][1]*si,t4=y[i][1]*co-x[i][1]*si;
            x[i][0]=t1,y[i][0]=t2,x[i][1]=t3,y[i][1]=t4;
    	}
    	for(int i=1;i<=n;i++){
    		if(x[i][0]>x[i][1])swap(x[i][0],x[i][1]),swap(y[i][0],y[i][1]);
    		sec[i]=sqrt(P(x[i][0]-x[i][1])+P(y[i][0]-y[i][1]))/(x[i][1]-x[i][0]);
    	}
    	for(int i=1;i<=n;i++)q[++m]=i,q[++m]=-i;
    	sort(q+1,q+m+1,comp);
    	for(int i=1;i<=m;i++)val[i]=0;
    	for(int i=1;i<=m;i++){
    		if(q[i]>0){
    			int u=q[i];X0=p[i]=x[u][0];
    			if(!up.empty())val[i]+=sec[up.begin()->u];
    			if(!down.empty())val[i]+=sec[down.begin()->u];
    			if(y[u][0]>0)up.insert(line(u));
    			else down.insert(line(u));
    		}
    		else{
    			int u=-q[i];X0=p[i]=x[u][1];
    			if(!up.empty())val[i]+=sec[up.begin()->u];
    			if(!down.empty())val[i]+=sec[down.begin()->u];
    			if(y[u][0]>0)up.erase(line(u));
    			else down.erase(line(u));
    		}
    	}
    	double res=0,ans=0,l=p[1]-len,r=p[1];int head=1,tail=2;
    	while(tail<=m){
    		double dl=p[head]-l,dr=p[tail]-r;
    		if(dl>dr)res+=(val[tail]-val[head])*dr,tail++,l+=dr,r+=dr;
    		else if(dl<dr)res+=(val[tail]-val[head])*dl,head++,l+=dl,r+=dl;
    		else res+=(val[tail]-val[head])*dl,head++,tail++,l+=dl,r+=dl;
    		ans=max(ans,res);
    	}
    	printf("%.13Lf
    ",ans);
    }
    int main(){
    	int T=read();
    	while(T--){
    		n=read(),m=0;
    		for(int i=1;i<=n;i++){
    			x[i][0]=read(),y[i][0]=read(),x[i][1]=read(),y[i][1]=read();
    		}
    		X0=read(),Y0=read(),X1=read(),Y1=read(),len=read();
    		if(X0>X1)swap(X1,X0),swap(Y1,Y0);
    		solve();
    	}
    }
    
  • 相关阅读:
    巧用 Patch Connect Plus 简化 Intune 第三方更新管理
    如何应对薄弱的企业安全意识
    Jira可视化数据分析解决方案
    终端安全:保护企业的关键
    为什么需要ITIL服务目录
    防抖、节流函数封装(站在巨人的肩膀上)
    vue服务器渲染--NUXT
    函数防抖,函数节流(站在巨人的肩膀上)
    MAC地址和IP地址的区别和联系(站在巨人的肩膀上)
    ES8新特性(2017)-- async/await详细介绍与使用
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/11145622.html
Copyright © 2011-2022 走看看