其他分享
首页 > 其他分享> > 【模板】【计几】旋转坐标(用于最小三角形以及三角形四边形面积存在性问题)

【模板】【计几】旋转坐标(用于最小三角形以及三角形四边形面积存在性问题)

作者:互联网

发现计算几何算法(瞎搞)真的是博大精深。

最大三角形和最大四边形都是旋转卡壳,有模板的。这里的方法还可以求最小三角形还有最小四边形,以及三角形面积存在性问题。

求最小三角形面积(n平方):bzoj3707.

参考:http://www.pianshen.com/article/772191644/

其实就是先把n方个直线按照斜率先排了序,然后所有点按照距离y轴距离排序(距离有正负),然后枚举的直线相当于y轴,每一次旋转 “ y轴 ” 的时候维护一下这个序列。然后我们发现维护这个序列只需要交换现在直线上的两点就好了。所以n方的。然后因为我们已经枚举两个点,找第三个点使得面积最小,由于已经维护了先前的序列,所以可以O(1)找到。(由于bzoj没有权限,所以我就羞耻的引用了别人的代码当模板了哈哈哈)。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const double pi=3.14159265358979;
 4 const int maxn=1005;
 5 const int M=1000010;
 6 struct point{
 7     double x,y;
 8     point(double _x=0,double _y=0){x=_x,y=_y;}
 9     friend inline point operator +(const point &a,const point &b){
10         return point(a.x+b.x,a.y+b.y);
11     }
12     friend inline point operator -(const point &a,const point &b){
13         return point(a.x-b.x,a.y-b.y);
14     }
15     friend inline double operator *(const point &a,const point &b){
16         return (a.x*b.y-a.y*b.x);
17     }
18 }p[maxn];
19 struct line{
20     int s,t;
21     double k;
22 }b[M];
23 int n,i,j,tot=0;
24 double ans=1e18;
25 int id[maxn],pos[maxn];
26 bool cmp(point a,point b){
27     if(a.x==b.x) return a.y<b.y;
28     return a.x<b.x;
29 }
30 bool Cmp(line a,line b){
31     return a.k<b.k;
32 }
33 double area(point u,line v){
34     return fabs((p[v.s]-u)*(p[v.t]-u))*0.5;
35 }
36 int main(){
37     scanf("%d",&n);
38     for(int i=1;i<=n;++i)
39     scanf("%lf%lf",&p[i].x,&p[i].y);
40     sort(p+1,p+n+1,cmp);
41     
42     for(int i=1;i<=n;++i) id[i]=pos[i]=i;
43     for(int i=1;i<=n;++i){
44         for(int j=i+1;j<=n;++j){
45             ++tot;
46             b[tot].s=i,b[tot].t=j;
47             if(p[i].x==p[j].x) b[tot].k=1e18;
48             else b[tot].k=(p[i].y-p[j].y)/(p[i].x-p[j].x);
49         }
50     }
51     sort(b+1,b+tot+1,Cmp);
52     //pos[i]存的是p[i]的排名 
53     //id[i]存的是 排名为i的点 
54     for(int i=1;i<=tot;++i){
55         int j=pos[b[i].s],k=pos[b[i].t];
56         if(j>k) swap(j,k);
57         if(j>1) ans=min(ans,area(p[id[j-1]],b[i]));
58         if(k<n) ans=min(ans,area(p[id[k+1]],b[i]));
59         if(ans==0) break; 
60         swap(pos[b[i].s],pos[b[i].t]);
61         swap(id[j],id[k]);
62     }
63     printf("%0.2f\n",ans);
64 }
View Code

 

接下来是求三角形面积存在性问题的:https://codeforces.com/problemset/problem/1019/D

其实就是刚刚的做法套个二分就好了。

标签:计几,const,point,int,double,return,四边形,三角形
来源: https://www.cnblogs.com/xiaobuxie/p/12222643.html