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

【模板】旋转卡壳求 面积最大的三角形 poj2079

时间:2019-10-13 17:04:02      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:stream   旋转   最大的   double   inline   void   display   两种   eve   

题目链接:https://vjudge.net/problem/POJ-2079

graham跑的巨慢,Andrew跑的巨快。还好写。

有两种写法。

旋转卡壳枚举三个点的(94ms)

技术图片
 1 /*************************************************************************
 2     > File Name: poj2079.cpp
 3 # File Name: poj2079.cpp
 4 # Author : xiaobuxie
 5 # QQ : 760427180
 6 # Email:760427180@qq.com
 7 # Created Time: 2019年10月12日 星期六 17时55分28秒
 8  ************************************************************************/
 9 
10 #include<iostream>
11 #include<cstdio>
12 #include<map>
13 #include<cmath>
14 #include<cstring>
15 #include<set>
16 #include<queue>
17 #include<vector>
18 #include<algorithm>
19 using namespace std;
20 typedef long long ll;
21 #define inf 0x3f3f3f3f
22 #define pq priority_queue<int,vector<int>,greater<int> >
23 ll gcd(ll a,ll b){
24     if(a<b) return gcd(b,a);
25     return b==0?a:gcd(b,a%b);
26 }
27 
28 const int N = 5e4+9;
29 struct Point{
30     double x,y;
31     bool operator < (const Point& b)const{
32         return x<b.x || (x==b.x && y<b.y);
33     }
34     Point operator - (const Point& b)const{
35         return (Point){x-b.x,y-b.y};
36     }
37     double operator ^ (const Point& b)const{
38         return x*b.y - b.x*y;
39     }
40 }p[N],ch[N];
41 int n;
42 inline void init(){
43     for(int i =0 ;i<n;++i) scanf("%lf %lf",&p[i].x,&p[i].y);
44 } 
45 inline int Andrew(){
46     sort(p,p+n);
47     int m = 0;
48     for(int i = 0; i < n;++i){
49         while( m>1 && ((p[i] - ch[m-2]) ^ (ch[m-1] - ch[m-2])) >=0) --m;
50         ch[m++] = p[i];
51     }
52     int k = m;
53     for(int i = n-2;i >= 0;--i){
54         while( m>k && ((p[i] - ch[m-2]) ^ (ch[m-1] - ch[m-2])) >=0) --m;
55         ch[m++] = p[i];
56     }
57     if(n>1) --m;
58     return m;
59 }
60 inline void rotate(){
61     double ans =0;
62     int m = Andrew();
63     int a = 1, b = 2;
64     for(int i = 0; i < m ;++i){
65         while( ((ch[a] - ch[i]) ^ (ch[(b+1)%m] - ch[i])) > ((ch[a] - ch[i]) ^ (ch[b] - ch[i]))){
66             b = (b+1)%m;
67         }
68         ans = max(ans,( (ch[a] - ch[i]) ^ (ch[b] - ch[i]) ));
69 
70         while( ((ch[(a+1)%m] - ch[i]) ^ (ch[b] - ch[i])) > ((ch[a] - ch[i]) ^ (ch[b] - ch[i]))){
71             a = (a+1)%m;
72         }
73         ans = max(ans,( (ch[a] - ch[i]) ^ (ch[b] - ch[i]) ));
74     }
75     ans /= 2.0;
76     printf("%.2f\n",ans);
77 }
78 int main(){
79     while(~scanf("%d",&n) && n!=-1){
80         init();
81         rotate();
82     }
83     return 0;
84 }
View Code

 

枚举两点之间差,再枚举第三个点的(391ms)

技术图片
 1 /*************************************************************************
 2     > File Name: poj2079.cpp
 3 # File Name: poj2079.cpp
 4 # Author : xiaobuxie
 5 # QQ : 760427180
 6 # Email:760427180@qq.com
 7 # Created Time: 2019年10月12日 星期六 17时55分28秒
 8  ************************************************************************/
 9 
10 #include<iostream>
11 #include<cstdio>
12 #include<map>
13 #include<cmath>
14 #include<cstring>
15 #include<set>
16 #include<queue>
17 #include<vector>
18 #include<algorithm>
19 using namespace std;
20 typedef long long ll;
21 #define inf 0x3f3f3f3f
22 #define pq priority_queue<int,vector<int>,greater<int> >
23 ll gcd(ll a,ll b){
24     if(a<b) return gcd(b,a);
25     return b==0?a:gcd(b,a%b);
26 }
27 
28 const int N = 5e4+9;
29 struct Point{
30     double x,y;
31     bool operator < (const Point& b)const{
32         return x<b.x || (x==b.x && y<b.y);
33     }
34     Point operator - (const Point& b)const{
35         return (Point){x-b.x,y-b.y};
36     }
37     double operator ^ (const Point& b)const{
38         return x*b.y - b.x*y;
39     }
40 }p[N],ch[N];
41 int n;
42 inline void init(){
43     for(int i =0 ;i<n;++i) scanf("%lf %lf",&p[i].x,&p[i].y);
44 } 
45 inline int Andrew(){
46     sort(p,p+n);
47     int m = 0;
48     for(int i = 0; i < n;++i){
49         while( m>1 && ((p[i] - ch[m-2]) ^ (ch[m-1] - ch[m-2])) >=0) --m;
50         ch[m++] = p[i];
51     }
52     int k = m;
53     for(int i = n-2;i >= 0;--i){
54         while( m>k && ((p[i] - ch[m-2]) ^ (ch[m-1] - ch[m-2])) >=0) --m;
55         ch[m++] = p[i];
56     }
57     if(n>1) --m;
58     return m;
59 }
60 inline void rotate(){
61     double ans =0;
62     int m = Andrew();
63     ch[m] = ch[0];
64     for(int ad = 1; ad <= m/2;++ad){
65         int now = (ad+1) % m;
66         for(int i = 0; i < m;++i){
67             int j = (i+ad) % m;
68             while( ((ch[j] - ch[i]) ^ (ch[now] - ch[i])) < ((ch[j] - ch[i]) ^ (ch[now+1] - ch[i]))){
69                     ++now;
70                     if(now == m) now = 0;
71             }
72             ans = max(ans,( (ch[j] - ch[i]) ^ (ch[now] - ch[i]) ));
73         }
74     }
75     ans /= 2.0;
76     printf("%.2f\n",ans);
77 }
78 int main(){
79     while(~scanf("%d",&n) && n!=-1){
80         init();
81         rotate();
82     }
83     return 0;
84 }
View Code

 

【模板】旋转卡壳求 面积最大的三角形 poj2079

标签:stream   旋转   最大的   double   inline   void   display   两种   eve   

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

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