洛谷P4166 [SCOI2007]最大土地面积

news/2025/3/14 16:39:57/

将四边形拆成两个三角形。旋转卡壳经典题。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
const int maxn = 2001;
const double eps = 1e-12;
const double PI = acos(-1.0);
int sgn(double x)
{if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;
}
struct Point
{double x,y;Point(){}Point(double _x,double _y){ x = _x;y = _y;}Point operator -(const Point &b)const{return Point(x - b.x,y - b.y);}
//叉积double operator ^(const Point &b)const{return x*b.y - y*b.x; }
//点积double operator *(const Point &b)const{return x*b.x + y*b.y; }
//绕原点旋转角度B(弧度值),后x,y的变化void transXY(double B){double tx = x,ty = y; x = tx*cos(B) - ty*sin(B);y = tx*sin(B) + ty*cos(B);}
};
struct Line
{Point s,e;Line(){}Line(Point _s,Point _e){ s = _s;e = _e;}pair<int,Point> operator &(const Line &b)const{Point res = s;if(sgn((s-e)^(b.s-b.e)) == 0){if(sgn((s-b.e)^(b.s-b.e)) == 0)return make_pair(0,res);//重合else return make_pair(1,res);//平行}double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));res.x += (e.x-s.x)*t;res.y += (e.y-s.y)*t;return make_pair(2,res);}
};
Point PointToLine(Point P,Line L)
{Point result;double t = ((P-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));result.x = L.s.x + (L.e.x-L.s.x)*t;result.y = L.s.y + (L.e.y-L.s.y)*t;return result;
}
double dist(Point a,Point b)
{return sqrt((a-b)*(a-b));
}
int dist2(Point a,Point b)
{return (a-b)*(a-b);
}
Point lis[maxn];
int Stack[maxn],top;
//相对于list[0]的极角排序bool _cmp(Point p1,Point p2)
{double tmp = (p1-lis[0])^(p2-lis[0]);if(sgn(tmp) > 0)return true;else if(sgn(tmp) == 0 && sgn(dist(p1,lis[0]) - dist(p2,lis[0])) <= 0)return true;else return false;
}
void Graham(int n)
{Point p0;int k = 0;p0 = lis[0];
//找最下边的一个点for(int i = 1;i < n;i++){if( (p0.y > lis[i].y) || (p0.y == lis[i].y && p0.x > lis[i].x) ){p0 = lis[i];k = i;}}swap(lis[k],lis[0]);sort(lis+1,lis+n,_cmp);if(n == 1){top = 1;Stack[0] = 0;return; }if(n == 2){top = 2;Stack[0] = 0;Stack[1] = 1;return ; }Stack[0] = 0;Stack[1] = 1;top = 2;for(int i = 2;i < n;i++){while(top > 1 &&sgn((lis[Stack[top-1]]-lis[Stack[top-2]])^(lis[i]-lis[Stack[top-2]])) <=0)top--;Stack[top++] = i;}
}
lint ans1[maxn][maxn],ans2[maxn][maxn],flag1[maxn][maxn],flag2[maxn][maxn];
void rotating_calipers(Point p[],int n)
{Point v;for( int i = 0;i < n;i++ ){lint cur = (i+2)%n;lint cur2 = i;for( int j = i+2; j < n ;j++ ){if( i == 0 && j == n-1 ) break;while( ((p[i] - p[j])^( p[(cur+1)%n] - p[cur] )) < 0 ) cur = (cur+1)%n;while( ((p[i] - p[j])^( p[(cur2+1)%n]-p[cur2] )) > 0 ) cur2 = (cur2+1)%n;ans1[i][j] = cur;flag1[i][j] = 1;ans2[i][j] = cur2;flag2[i][j] = 1;}}return;
}
Point p[maxn];
int main(){lint n;double x,y;lint tot = 0;scanf("%d",&n);for( lint i = 1;i <= n;i++ ){scanf("%lf%lf",&x,&y);lis[tot++] = Point( x,y );}Graham(n);for( lint i = 0;i < top;i++ ){p[i] = lis[Stack[i]];}rotating_calipers( p,top );double ans  = 0;for( lint i = 0;i < top;i++ ){for( lint j = 0;j < top;j++ ){if( flag1[i][j]&&flag2[i][j] ){Point x = p[i] - p[j];Point y1 = p[ans1[i][j]] - p[j];Point y2= p[ ans2[i][j] ] - p[j];ans = max( ans,(abs((x^y1)) + abs((x^y2)))/2 );}}}printf("%.3lf\n",ans);return 0;
}

 水平排序版本

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef int lint;
const int maxn = 2001;
const double eps = 1e-12;
const double PI = acos(-1.0);
int sgn(double x)
{if(fabs(x) < eps)return 0;if(x < 0)return -1;else return 1;
}
struct Point
{double x,y;Point(){}Point(double _x,double _y){ x = _x;y = _y;}Point operator -(const Point &b)const{return Point(x - b.x,y - b.y);}
//叉积double operator ^(const Point &b)const{return x*b.y - y*b.x; }
//点积double operator *(const Point &b)const{return x*b.x + y*b.y; }
//绕原点旋转角度B(弧度值),后x,y的变化void transXY(double B){double tx = x,ty = y; x = tx*cos(B) - ty*sin(B);y = tx*sin(B) + ty*cos(B);}
};
struct Line
{Point s,e;Line(){}Line(Point _s,Point _e){ s = _s;e = _e;}pair<int,Point> operator &(const Line &b)const{Point res = s;if(sgn((s-e)^(b.s-b.e)) == 0){if(sgn((s-b.e)^(b.s-b.e)) == 0)return make_pair(0,res);//重合else return make_pair(1,res);//平行}double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));res.x += (e.x-s.x)*t;res.y += (e.y-s.y)*t;return make_pair(2,res);}
};
Point PointToLine(Point P,Line L)
{Point result;double t = ((P-L.s)*(L.e-L.s))/((L.e-L.s)*(L.e-L.s));result.x = L.s.x + (L.e.x-L.s.x)*t;result.y = L.s.y + (L.e.y-L.s.y)*t;return result;
}
double dist(Point a,Point b)
{return sqrt((a-b)*(a-b));
}
int dist2(Point a,Point b)
{return (a-b)*(a-b);
}
Point lis[maxn];
int Stack[maxn],top;
//相对于list[0]的极角排序bool _cmp(Point p1,Point p2)
{if( !sgn( p1.x-p2.x ) ) return p1.y < p2.y;return p1.x < p2.x;
}
void Graham(int n)
{sort(lis,lis+n,_cmp);top = 0;for(int i = 0;i < n;i++){while(top > 1 &&sgn((lis[Stack[top-1]]-lis[Stack[top-2]])^(lis[i]-lis[Stack[top-2]])) <=0)top--;Stack[top++] = i;}int k = top;for( int i = n-2;i >= 0;i-- ){while( top > k && sgn((lis[Stack[top-1]]-lis[Stack[top-2]])^(lis[i]-lis[Stack[top-2]])) <=0 ){top--;}Stack[ top++ ] = i;}top--;
}
lint ans1[maxn][maxn],ans2[maxn][maxn],flag1[maxn][maxn],flag2[maxn][maxn];
void rotating_calipers(Point p[],int n)
{Point v;for( int i = 0;i < n;i++ ){lint cur = (i+2)%n;lint cur2 = i;for( int j = i+2; j < n ;j++ ){if( i == 0 && j == n-1 ) break;while( ((p[i] - p[j])^( p[(cur+1)%n] - p[cur] )) < 0 ) cur = (cur+1)%n;while( ((p[i] - p[j])^( p[(cur2+1)%n]-p[cur2] )) > 0 ) cur2 = (cur2+1)%n;ans1[i][j] = cur;flag1[i][j] = 1;ans2[i][j] = cur2;flag2[i][j] = 1;}}return;
}
Point p[maxn];
int main(){lint n;double x,y;lint tot = 0;scanf("%d",&n);for( lint i = 1;i <= n;i++ ){scanf("%lf%lf",&x,&y);lis[tot++] = Point( x,y );}Graham(n);for( lint i = 0;i < top;i++ ){p[i] = lis[Stack[i]];}rotating_calipers( p,top );double ans  = 0;for( lint i = 0;i < top;i++ ){for( lint j = 0;j < top;j++ ){if( flag1[i][j]&&flag2[i][j] ){Point x = p[i] - p[j];Point y1 = p[ans1[i][j]] - p[j];Point y2= p[ ans2[i][j] ] - p[j];ans = max( ans,(abs((x^y1)) + abs((x^y2)))/2 );}}}printf("%.3lf\n",ans);return 0;
}

 


http://www.ppmy.cn/news/243413.html

相关文章

BZOJ 1069 Luogu P4166 最大土地面积 (凸包)

题目链接: (bzoj)https://www.lydsy.com/JudgeOnline/problem.php?id1069 (luogu)https://www.luogu.org/problemnew/show/P4166 题解: 水题&#xff0c;凸包极角排序之后枚举凸四边形对角线\(i,j\)然后找面积最大的点\(k\)&#xff0c;\(k\)随着\(i,j\)是单调的 但是有个易错…

Android中的Intent(显示隐式)

Android中的Intent(显示&隐式) 显示Intent 显示Intent是明确目标Activity的类名 通过Intent(Context packageContext, Class<?> cls)构造方法Intent intent new Intent(this, SecondActivity.class) startActivity(intent);通过Intent的setComponent()方法Componen…

NLP的idea,看了就能水一篇论文

1.问题 在中文情感分析任务中,已有方法仅从单极、单尺度来考虑情感特征&#xff0c;无法充分挖掘和利用情感特征信息&#xff0c;模型性能不理想。 单级单尺度&#xff1a;只从一个方面学习文本的特征 多级多尺度&#xff1a;应该是分别从不同方面学习文本的特征&#xff0c…

一键提升分辨率,呈现更清晰、更细腻的视觉盛宴

牛学长视频修复工具是一款使用AI技术对你的视频分辨率就行调整放大清晰的软件&#xff0c;最高支持8K超高清。 现如今&#xff0c;视频成为人们记录生活、表达创意的重要方式之一。然而&#xff0c;我们常常遇到一个问题&#xff1a;旧有的视频素材分辨率低&#xff0c;画质模…

priority_queue的模拟实现和仿函数

priority_queue模拟 首先查看源代码&#xff0c;源代码就在queue剩下的部分中 push_heap是STL库中的堆算法&#xff0c;STL库中包装有支持堆的算法&#xff0c;在algorithm.h中&#xff1a; 只要不断用堆的形式插入数据&#xff0c;就会形成堆。 priority_queue模拟——初版 pr…

网络协议——STP协议是什么?是如何实现的?

作者&#xff1a;Insist-- 个人主页&#xff1a;insist--个人主页 作者会持续更新网络知识和python基础知识&#xff0c;期待你的关注 目录 一、STP协议是什么 二、为什么需要STP协议 三、STP的实现过程 ​编辑 1、选举跟桥 2、给非跟桥交换机选举跟端口 3、给每个网段选…

正在解析主机 mirrors.aliyun.com (mirrors.aliyun.com)失败:未知的名称或服务。wget无法解析主机地址

网络问题&#xff1a;做个记录 我这边是更改了链接方式没有问题了就因为之前安装时使用的是nat方式 后来未关机的情况下改成了桥连接出现的问题。ping不通www.baidu.com

CP2102和CP2104的区别

主要区别&#xff1a; 1. CP2104更便宜。 2. CP2104体积更小&#xff0c;占地面积不同。CP2104是QFN24&#xff08;4x4mm&#xff09;; CP2102是QFN28&#xff08;5x5mm&#xff09;。 3. CP2104具有 I/O 电源引脚&#xff0c;可通过外部电阻承受VDD至5V的电压。 4. CP2104支持…