[SDOI2018]物理实验 set,扫描线,旋转坐标系

链接

[loj](#2561. 「SDOI2018」物理实验)

思路

先将导轨移到原点,然后旋转坐标系,参考博客

然后分线段,每段的贡献(三角函数值)求出来,用自己喜欢的平衡树,我选set。

显然答案的一端是小线段的端点。

然后扫描线求出最大的ans。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+7;
int n,op[N];
long double X[N][2],Y[N][2],x[2],y[2],nx,csc[N],val[N<<1],pos[N<<1],L;
bool cmp(int x,int y) {
return ((x>0) ? X[x][0] : X[-x][1]) < ((y>0) ? X[y][0] : X[-y][1]);
}
struct node {
int u;
node(int x=0) {u=x;}
bool operator < (const node &b) const {
if(u==b.u) return 0;
long double tmp1=(Y[u][1]-Y[u][0])/(X[u][1]-X[u][0])*(nx-X[u][0])+Y[u][0];
long double tmp2=(Y[b.u][1]-Y[b.u][0])/(X[b.u][1]-X[b.u][0])*(nx-X[b.u][0])+Y[b.u][0];
return ((tmp1>0) ? tmp1 : -tmp1) < ((tmp2>0) ? tmp2 : -tmp2);
}
};
set<node> up,down;
void solve() {
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%Lf%Lf%Lf%Lf",&X[i][0],&Y[i][0],&X[i][1],&Y[i][1]);
scanf("%Lf%Lf%Lf%Lf%Lf",&x[0],&y[0],&x[1],&y[1],&L);
long double dx=x[0]-x[1],dy=y[0]-y[1];
for(int i=1;i<=n;++i) csc[i]=sqrt((X[i][0]-X[i][1])*(X[i][0]-X[i][1])+(Y[i][0]-Y[i][1])*(Y[i][0]-Y[i][1]));
long double dw=(x[0]!=x[1]) ? y[1]-(dy/dx)*x[1] : 0;
long double dis=sqrt(dx*dx+dy*dy);
for(int i=1;i<=n;++i) Y[i][0]-=dw,Y[i][1]-=dw;
dx/=dis,dy/=dis;
for(int i=1;i<=n;++i) {
long double tmp1,tmp2,tmp3,tmp4;
tmp1=dx*X[i][0]+dy*Y[i][0],
tmp2=dx*X[i][1]+dy*Y[i][1],
tmp3=dx*Y[i][0]-dy*X[i][0],
tmp4=dx*Y[i][1]-dy*X[i][1];
X[i][0]=tmp1,
X[i][1]=tmp2,
Y[i][0]=tmp3,
Y[i][1]=tmp4;
if(X[i][0]>X[i][1]) {
swap(X[i][0],X[i][1]);
swap(Y[i][0],Y[i][1]);
}
csc[i]/=(X[i][1]-X[i][0]);
op[i]=-i,op[i+n]=i;
}
sort(op+1,op+1+2*n,cmp);
for(int i=1;i<=2*n;++i) {
if(op[i]>0) {
nx=pos[i]=X[op[i]][0];
(Y[op[i]][0]>0 ? up : down).insert(node(op[i]));
if(!up.empty()) val[i]+=csc[up.begin()->u];
if(!down.empty()) val[i]+=csc[down.begin()->u];
} else {
nx=pos[i]=X[-op[i]][1];
(Y[-op[i]][1]>0 ? up : down).erase(node(-op[i]));
if(!up.empty()) val[i]+=csc[up.begin()->u];
if(!down.empty()) val[i]+=csc[down.begin()->u];
}
}
for(int i=2*n;i>=1;--i) val[i]=val[i-1];
long double attack=0,ll=pos[1]-L,rr=pos[1],ans=0;
int pl=1,pr=2;
while(pr<=2*n) {
long double dl=pos[pl]-ll;
long double dr=pos[pr]-rr;
if(dl>dr) {
attack+=(val[pr]-val[pl])*dr;
pr++;
ll+=dr;
rr+=dr;
} else if(dl<dr) {
attack+=(val[pr]-val[pl])*dl;
pl++;
ll+=dl;
rr+=dl;
} else {
attack+=(val[pr]-val[pl])*dl;
pr++;
pl++;
ll+=dl;
rr+=dl;
}
ans=max(ans,attack);
}
printf("%.7Lf\n",ans);
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
memset(val,0,sizeof(val));
solve();
}
return 0;
}

[SDOI2018]物理实验 set,扫描线,旋转坐标系的更多相关文章

  1. bzoj5328: [Sdoi2018]物理实验

    果然我还是太菜了,爆了一天才过....隔壁肉丝都不知道喊了多少句哎╮(╯▽╰)╭我又A了什么傻逼题(然鹅就是wf和国集的题QWQ) 其实这个题就是个裸题,但是我就是不会... 这个题第一步就是明显的旋 ...

  2. SDOI2018物理实验

    /* 向量运算不会呐 抄了一个长度几百行的模板 一直过不了编译 醉了 还是抄了大佬的代码 首先把所有的线段投影到 导轨上 然后用set 分上和下分别维护一下 距离导轨最近的线段 是能够照射到的 可以证 ...

  3. VPython—旋转坐标系

    使用arrow( )创建三个坐标轴代表一个坐标系,其中X0-Y0-Z0为参考坐标系(固定不动),X-Y-Z为运动坐标系,这两个坐标系原点重合,运动坐标系可以绕参考坐标系或其自身旋转.在屏幕上输出一个转 ...

  4. 【bzoj3170】[Tjoi 2013]松鼠聚会 旋转坐标系

    题目描述 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. 输入 ...

  5. 【bzoj2989】数列 KD-tree+旋转坐标系

    题目描述 给定一个长度为n的正整数数列a[i]. 定义2个位置的graze值为两者位置差与数值差的和,即graze(x,y)=|x-y|+|a[x]-a[y]|. 2种操作(k都是正整数): 1.Mo ...

  6. [bzoj2989]数列_KD-Tree_旋转坐标系

    数列 bzoj-2989 题目大意:题目链接. 注释:略. 想法:显然,我们用x和a[x]两个值建立笛卡尔坐标系. 两个点之间的距离为曼哈顿距离. 修改操作就是插入... 查询操作就是查询一个点周围的 ...

  7. HDU 6538 Neko and quadrilateral(极角排序+旋转坐标系)

    这道题简直太好了,对于计算几何选手需要掌握的一个方法. 首先对于求解四边形面积,我们可以将四边形按对角线划分成两个三角形,显然此时四边形的面积最大最小值就变成了求解里这个对角线最近最远的点对. 对于此 ...

  8. 「SDOI2018」物理实验

    题目大意: 这题不好描述,直接看原题吧…… 题解: 很无脑的题……就是卡精度+难写.代码能力还是太差了. 其实可以直接用long double肝过去.但我的代码似乎太丑了,以至于跑得奇慢无比. 代码: ...

  9. Android canvas rotate():平移旋转坐标系至任意原点任意角度-------附:android反三角函数小结

    自然状态下,坐标系以屏幕左上角为原点,向右是x正轴,向下是y正轴.现在要使坐标系的原点平移至任一点O(x,y),且旋转a角度,如何实现? 交待下我的问题背景,已知屏幕上有两点p1和p2,构成直线l.我 ...

随机推荐

  1. 调试MATLAB代码

    1.在子函数设置的断点,在运行时,不起作用: 因为在主函数开始时,使用了clear all,在运行时,会把断点给删除.

  2. Rider 中无法显示DataTable,VS2019的.netCore才有DataTable可视化工具(4)

    如下图在vs2017中是这样的 在2019中是可以直接看的 在Rider中无论什么项目都不支持.

  3. Qt 的两个许可证区别分析:LGPL 和商业协议

    Qt 的两个许可证区别分析:LGPL 和商业协议 Qt 有两个许可证:LGPL 和商业协议.这两个协议在现在的 Qt 版本中的代码是完全一致的(潜在含义是,Qt 的早期版本,商业版的 Qt 通常包含有 ...

  4. Jmeter使用笔记1

    1.简介 jmeter 是一款专门用于功能测试和压力测试的轻量级测试开发平台.多数情况下是用作压力测试,该测试工具在阿里巴巴有着广泛的使用. 2.安装 下载apache-jmeter-3.1.rar; ...

  5. 剑指Offer_Java_顺时针打印矩阵(二维数组)

    顺(逆)时针打印矩阵 算法思想: 简单来说,就是不断地收缩矩阵的边界 定义四个变量代表范围,up(初始0).down(初始-行高).left(初始-0).right(初始-列宽), 向右走存入整行的值 ...

  6. 我是如何一步步编码完成万仓网ERP系统的(二)前端框架

    https://www.cnblogs.com/smh188/p/11533668.html(我是如何一步步编码完成万仓网ERP系统的(一)系统架构) https://www.cnblogs.com/ ...

  7. alpine使用的避坑指南

    alpine,是一个重量仅为5 MB的最小Linux发行版.它还有基本的linux工具和一个不错的包管理器APK.APK非常稳定,有相当数量的包.由于体积小,在容器中很受欢迎,但是使用上坑也很多,大部 ...

  8. django framework插件类视图方法

    1.使用类视图APIView重写API 类视图APIView,取代@api_view装饰器,代码如下: from rest_framework import status from rest_fram ...

  9. django_restframework项目之python虚拟环境配置(一)

    虚拟环境的搭建 优点 1.使不同应用开发环境相互独立 2.环境升级不影响其他应用,也不会影响全局的python环境 3.防止出现包管理混乱及包版本冲突 windows 安装 # 建议使用pip3安装到 ...

  10. TRACE32 Simulator License

    链接:https://www.lauterbach.com/frames.html?sim_license.html Which Features of the TRACE32 Instruction ...