码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】【计几】最大四边形

时间:2020-01-22 21:33:39      阅读:83      评论:0      收藏:0      [点我收藏+]

标签:alt   cer   splay   opened   lse   event   assert   continue   open   

题目链接:https://codeforces.com/group/uVAsoW2Jkj/contest/265761

L题。

类似于旋转卡壳:

技术图片
 1 #include<iostream>
 2 #include<cassert>
 3 #include<bits/stdc++.h>
 4 using namespace std;
 5 typedef long long ll;
 6 const int N = 4100;
 7 #define eps 1e-10
 8 struct Point{
 9     ll x,y,id;
10     bool operator < (const Point& b)const{
11         return x < b.x || (x==b.x && y < b.y);
12     }
13     Point operator - (const Point& b)const{
14         return (Point){ x - b.x,y - b.y};
15     }
16     ll operator ^ (const Point b)const{
17         return x * b.y - b.x * y;
18     }
19 }p[N],ch[N],p0;
20 ll cross(Point o,Point a,Point b){
21     return (a.x - o.x) * (b.y - o.y) - (b.x - o.x) * (a.y - o.y);
22 }
23 ll area(Point o,Point a,Point b){
24     ll tem = cross(o,a,b);
25     if(tem < 0) tem = -tem;
26     return tem;
27 }
28 int n,m;
29 int Andrew(){
30     sort(p,p+n);
31     m = 0;
32     for(int i = 0;i<n;++i){
33         while( m > 1 && ( (p[i] - ch[m-2]) ^ (ch[m-1] - ch[m-2]) ) >= 0 ) --m;
34         ch[m++] = p[i];
35     }
36     int k = m;
37     for(int i = n-2;i>=0;--i){
38         while( m > k && ( (p[i] - ch[m-2]) ^ ( ch[m-1] - ch[m-2])) >= 0 ) --m;
39         ch[m++] = p[i];
40     }
41     if(n>1) --m;
42     return m;
43 }
44 int main(){
45     int T; scanf("%d",&T);
46     while(T--){
47         scanf("%d",&n);
48         for(int i = 0;i<n;++i) scanf("%lld %lld",&p[i].x,&p[i].y),p[i].id = i;
49         Andrew();
50         ll ans = 0;
51         if(m==3){
52             ll all = area(ch[0],ch[1],ch[2]);
53             ll tem = 1000000000000000000;
54             for(int i = 0;i<n;++i){
55                 if(p[i].id == ch[0].id || p[i].id == ch[1].id || p[i].id == ch[2].id) continue;
56                 tem = min( tem,min( min(area(p[i],ch[0],ch[1]),area(p[i],ch[0],ch[2])), area(p[i],ch[1],ch[2]) ));
57             }
58             ans = all - tem;
59         }else if(m > 3){
60             for(int k = 0;k<m;++k){
61                 int l = 1,r = 3;
62                 for(int i = 2;i<m-1;++i){
63                     while( l+1 < i && area(ch[0],ch[l+1],ch[i]) >= area(ch[0],ch[l],ch[i])) ++l;
64                     while( r+1 < m && area(ch[0],ch[r+1],ch[i]) >= area(ch[0],ch[r],ch[i])) ++r;
65                     ans = max(ans,area(ch[0],ch[i],ch[r]) + area(ch[0],ch[i],ch[l]));
66                     //if(ch[0].x == 1 && ch[0].y == 2) cerr<<"l r"<<l<<" "<<r<<" "<<" "<<i<<"i"<<area(ch[0],ch[i],ch[r]) <<" "<< area(ch[0],ch[i],ch[l])<<endl;
67                 }
68                 //cerr<<ch[0].x<<" "<<ch[0].y<<" "<<ans<<endl;
69                 //if(ch[0].x == 1 && ch[0].y == 2) for(int i = 0;i<m;++i) cerr<<ch[i].x<<" "<<ch[i].y<<"a"<<endl;
70                 ch[m] = ch[0];
71                 for(int i = 0;i<m;++i) ch[i] = ch[i+1];
72             }
73         }
74         if(ans&1) printf("%lld.5\n",ans/2);
75         else printf("%lld\n",ans/2);
76     }
77     return 0;
78 }
View Code

【模板】【计几】最大四边形

标签:alt   cer   splay   opened   lse   event   assert   continue   open   

原文地址:https://www.cnblogs.com/xiaobuxie/p/12229616.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!