【BZOJ3707】圈地 计算几何 旋转坐标系

链接:

#include <stdio.h>
int main()
{
    puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢");
    puts("网址:blog.csdn.net/vmurder/article/details/46608743");
}

题解:

对于一个点对,如果它的连线的方程的 x 为定值 ,即为一条竖线,那么我可以把所有点以 x 为第一键值, y 为第二键值排序,然后这条线两端的第一个点与这条线段做个三角形,其面积都可能更新答案。。

然后我们可以先把所有线按照斜率排个序,然后发现每次按序修改y轴,可以 O(1) 得到旋转坐标系后的点的序列。

可以观察此图(这是个小特例福利哦):

呃。就是每次旋转到一条斜率时,旋转前是是斜的 (A?>B),旋转完就变成了竖着的 (B?>A) ,此时只要简单交换一下 A、B 在序列中位置就好了~如下图:

代码:

(我才不会告诉你们虽然AC,但是实测时感觉貌似哪里挂了呢QwQ)

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 1010
#define INF 1e60
#define Area(A,B,C) abs(xmul(A,B)+xmul(B,C)+xmul(C,A))
using namespace std;
struct Point
{
    double x,y;
    void read(){scanf("%lf%lf",&x,&y);}
    bool operator < (const Point &A)const{return x<A.x;}
}p[N],Zero;
int id[N],cr[N];
struct Line
{
    int u,v; // 点标号……
    double k;
    void keep(int _u,int _v)
    {u=_u,v=_v,k=(p[u].y-p[v].y)/(p[u].x-p[v].x);}
    bool operator < (const Line &A)const{return k<A.k;}
}l[N*N];
inline double xmul(Point B,Point C,Point A=Zero)
{return (C.y-A.y)*(B.x-A.x)-(B.y-A.y)*(C.x-A.x);}

int n,m;
double ans=INF;

void work(int u,int v)
{
    if(id[u]>id[v])swap(u,v);
    if(id[u]>1)ans=min(ans,Area(p[u],p[v],p[cr[id[u]-1]]));
    if(id[v]<n)ans=min(ans,Area(p[u],p[v],p[cr[id[v]+1]]));
    swap(id[u],id[v]),cr[id[u]]=u,cr[id[v]]=v;
}

int main()
{
//  freopen("test.in","r",stdin);

    int i,j;

    scanf("%d",&n);
    for(i=1;i<=n;i++)
    {
        p[i].read();
        id[i]=cr[i]=i;
    }
    sort(p+1,p+n+1);
    for(i=1;i<=n;i++)for(j=i+1;j<=n;j++)
        l[++m].keep(i,j);
    sort(l+1,l+m+1);
    for(i=1;i<=m;i++)work(l[i].u,l[i].v);
    printf("%.2lf\n",ans/2.0);

    return 0;
}
时间: 2024-10-08 13:42:54

【BZOJ3707】圈地 计算几何 旋转坐标系的相关文章

VPython—旋转坐标系

使用arrow( )创建三个坐标轴代表一个坐标系,其中X0-Y0-Z0为参考坐标系(固定不动),X-Y-Z为运动坐标系,这两个坐标系原点重合,运动坐标系可以绕参考坐标系或其自身旋转.在屏幕上输出一个转换矩阵,该矩阵描述了动坐标系相对于参考坐标系的姿态,矩阵第一列表示动坐标系的X轴在参考坐标系中的方向,第二列表示动坐标系的Y轴在参考坐标系中的方向,第二列表示动坐标系的Z轴在参考坐标系中的方向.显而易见,当两个坐标系姿态一致时,转换矩阵为3阶单位矩阵. 程序中按键盘的上下方向坐标系绕Y轴旋转,按左右

【BZOJ3170】[Tjoi 2013]松鼠聚会 旋转坐标系

[BZOJ3170][Tjoi 2013]松鼠聚会 有N个小松鼠,它们的家用一个点x,y表示,两个点的距离定义为:点(x,y)和它周围的8个点即上下左右四个点和对角的四个点,距离为1.现在N个松鼠要走到一个松鼠家去,求走过的最短距离. Input 第一行给出数字N,表示有多少只小松鼠.0<=N<=10^5下面N行,每行给出x,y表示其家的坐标.-10^9<=x,y<=10^9 Output 表示为了聚会走的路程和最小为多少. Sample Input 6 -4 -1 -1 -2 2

BZOJ3707 圈地

只会O(n ^ 3)路过= = OrzOrzOrzOrzOrz "出题人题解: 显然,这时候暴力枚举会T.于是我们转变一下思路,如果我们确定了2个点以后,第三个点有必要去盲目的枚举吗?答案是否定的.实际上我们把经过这两点的线看成一个斜率,把他当成y轴你会发现第三个点明显是在坐标系左右找一个离”y轴”最近的点来算面积更新答案.然后我们可以继续思考,发现我们可以把点按照某个斜率当成”y轴”进行“从左到右”的排序,这样当2点共线的时候,用这两个点的左右2个点去更新答案就好了.也就是说我们采用旋转坐标系

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

[SDOI2018]物理实验 set,扫描线,旋转坐标系 链接 loj 思路 先将导轨移到原点,然后旋转坐标系,参考博客. 然后分线段,每段的贡献(三角函数值)求出来,用自己喜欢的平衡树,我选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

BZOJ 3707: 圈地 计算几何

Description 2维平面上有n个木桩,黄学长有一次圈地的机会并得到圈到的土地,为了体现他的高风亮节,他要使他圈到的土地面积尽量小.圈地需要圈一个至少3个点的多边形,多边形的顶点就是一个木桩,圈得的土地就是这个多边形内部的土地.(因为黄学长非常的神,所以他允许圈出的第n点共线,那样面积算0) Input 第一行一个整数n,表示木桩个数.接下来n行,每行2个整数表示一个木桩的坐标,坐标两两不同. 题解: 简单的说就是给定平面上n个点,求这n个点组成三角形的最小面积. 如果分别枚举三个点的话是

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

自然状态下,坐标系以屏幕左上角为原点,向右是x正轴,向下是y正轴.现在要使坐标系的原点平移至任一点O(x,y),且旋转a角度,如何实现? 交待下我的问题背景,已知屏幕上有两点p1和p2,构成直线l.我要以两点的中点mid(x,y)为坐标原点,线段l的中垂线为一个轴,l为另外一个轴,做一个坐标系.切割出一个边长为d的正方形.示意图如下所示: double d = Math.sqrt((p2.x-p1.x)*(p2.x - p1.x)+(p2.y-p1.y)*(p2.y-p1.y)); //p1.p

旋转坐标系

'Origin on WCS point: 0,0,6150 'Rotation of the Zaxis: -90 degrees 'Rotation of the Yaxis: 6 degrees 'Rotation of the Xaxis: 35 degrees 'Rotation of the Yaxis: -9- degrees Dim UCS As Matrix3d = Matrix3d.Identity * _ Matrix3d.Displacement(New Vector3d

[FJSC2014]圈地

[题目描述] 2维平面上有n个木桩,黄学长有一次圈地的机会并得到圈到的土地,为了体现他的高风亮节,他要使他圈到的土地面积尽量小.圈地需要圈一个至少3个点的多边形,多边形的顶点就是一个木桩,圈得的土地就是这个多边形内部的土地.(因为黄学长非常的神,所以他允许圈出的第n点共线,那样面积算0) [输入格式] 第一行一个整数n,表示木桩个数. 接下来n行,每行2个整数表示一个木桩的坐标,坐标两两不同. [输出格式] 仅一行,表示最小圈得的土地面积,保留2位小数. [样例输入] 样例1:3 0 0 0 1

四元数运动学笔记(3)四元数和旋转相关的约定表述

1.四元数的约定表述1.1 四元数表述的差异1.2 Hamilton vs JPL1.2.1元素的顺序1.2.2 左手系和右手系1.2.3 旋转操作的对象1.2.4 旋转操作的方向1.3 文章采用的表述1.4扰动和时间导数1.4.1右扰动和左扰动1.4.2 Hamilton表示下的(L-G)的四元数时间导数1.4.3 其他有用的表述方式1.5 barfoot书中表述2.旋转角速率表示旋转积分2.1零阶积分2.2一阶积分2.3归一化处理 1.四元数的约定表述 1.1 四元数表述的差异 根据实部虚部