1.找凸包的最小宽度
#include <bits/stdc++.h>
using namespace std;
double EPS=1e-10;
//考虑误差的加法运算
double add(double a,double b){
if(fabs(a+b)<EPS*(fabs(a)+fabs(b))) return 0;
return a+b;
}
struct P{
double x,y;
P(){}
P(double x,double y):x(x),y(y){}
P operator +(P p){
return P(add(x,p.x),add(y,p.y));
}
P operator -(P p){
return P(add(x,-p.x),add(y,-p.y));
}
P operator *(double d){
return P(x*d,y*d);
}
double dot(P p){ //内积
return add(x*p.x,y*p.y);
}
double det(P p){//外积
return add(x*p.y,-y*p.x);
}
};
P ps[2020000];
bool cmp(P a,P b){
return a.x!=b.x?a.x<b.x:a.y<b.y;
}
vector <P> convex_hull(P*ps,int n){
sort(ps,ps+n,cmp);
int k=0;//凸包的顶点数
vector <P> qs(n<<1); //构造中的凸包
for(int i=0;i<n;i++){//构造凸包的下侧
while(k>1&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) k--;
qs[k++]=ps[i];
}
for(int i=n-2,t=k;i>=0;i--){//构造凸包的上侧
while(k>t&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) k--;
qs[k++]=ps[i];
}
qs.resize(k-1);
return qs;
}
//叉积
double cross(P a,P b,P c){
return fabs((a-b).det(a-c));
}
//距离的平方
double dist(P a,P b){
return (a-b).dot(a-b);
}
int main(){
int n,r;
cin>>n>>r;
for(int i=0;i<n;i++){
cin>>ps[i].x>>ps[i].y;
}
vector <P> qs=convex_hull(ps,n);
n=qs.size();
if(n==2){//特殊处理凸包退化的情况
printf("%.15lf\n",0.0);
return 0;
}
double ans=1e20;
int temp=2;
int u;
for(int i=0;i<n;i++){
double d=sqrt(dist(qs[i],qs[(i+1)%n]));
// printf("i=%d\n",i );
u=temp;
// printf("%d %d %d\n",i,(i+1)%n,u );
double emm=0;
while(cross(qs[i],qs[(i+1)%n],qs[u])<=cross(qs[i],qs[(i+1)%n],qs[(u+1)%n])){
double height = cross(qs[i],qs[(i+1)%n],qs[u])/d;
emm=max(height,emm);
u=(u+1)%n;
}
temp=u;
emm=max(emm,cross(qs[i],qs[(i+1)%n],qs[u])/d);
//面积最大
ans=min(ans,emm);
}
printf("%.15lf\n",ans );
return 0;
}
2.踢足球
s1->t1
s2->t2
轨迹是否可以不相交
场上还有其他队员可以中转
需要预处理凸包~
一开始就不相交 直接特判
否则如果四个点都在凸包上 false
其他情况true
#include <bits/stdc++.h>
using namespace std;
double EPS=1e-10;
int sgn(double x){//符号函数 注意是int
return fabs(x)<EPS?0:(x>0?1:-1);
}
//考虑误差的加法运算
double add(double a,double b){
if(fabs(a+b)<EPS*(fabs(a)+fabs(b))) return 0;
return a+b;
}
struct P{
double x,y;
P(){}
P(double x,double y):x(x),y(y){}
P operator +(P p){
return P(add(x,p.x),add(y,p.y));
}
P operator -(P p){
return P(add(x,-p.x),add(y,-p.y));
}
P operator *(double d){
return P(x*d,y*d);
}
double dot(P p){ //内积
return add(x*p.x,y*p.y);
}
double det(P p){//外积
return add(x*p.y,-y*p.x);
}
bool operator ==(P p){
return x==p.x&&y==p.y;
}
};
P ps[2020000],s1,s2,t1,t2;
bool cmp(P a,P b){
return a.x!=b.x?a.x<b.x:a.y<b.y;
}
vector <P> convex_hull(P*ps,int n){
sort(ps,ps+n,cmp);
int k=0;//凸包的顶点数
vector <P> qs(n<<1); //构造中的凸包
for(int i=0;i<n;i++){//构造凸包的下侧
while(k>1&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) k--;
qs[k++]=ps[i];
}
for(int i=n-2,t=k;i>=0;i--){//构造凸包的上侧
while(k>t&&(qs[k-1]-qs[k-2]).det(ps[i]-qs[k-1])<=0) k--;
qs[k++]=ps[i];
}
qs.resize(k-1);
return qs;
}
//叉积
double cross(P a,P b,P c){
return fabs((a-b).det(a-c));
}
//距离的平方
double dist(P a,P b){
return (a-b).dot(a-b);
}
bool intersect(P a,P b,P c,P d){
if(sgn((b-a).det(c-a))==sgn((b-a).det(d-a))) return false;
if(sgn((c-a).det(d-a))==sgn((c-b).det(d-b))) return false;
return true;
}
bool intersect_self(P a,P b,P c,P d){//判断线段ab 线段cd是否相交 true相交 自己写的判断线段相交版本
//快速排斥实验
//ab中最大的x小于cd中最小的x
//ab中最大的y小于cd中最小的y
//cd中最大的x小于ab中最小的x
//cd中最大的y小于ab中最小的y
if(max(a.x,b.x)<min(c.x,d.x)||
max(a.y,b.y)<min(c.y,d.y)||
max(c.x,d.x)<min(a.x,b.x)||
max(c.y,d.y)<min(a.y,b.y)
){
return false;
}
//跨立实验
if((a-d).det(c-d) * (b-d).det(c- d)>0||
(c-a).det(b-a)*(d-a).det(b-a)>0
){
return false;
}
return true;
}
struct mapcmp{
bool operator ()(const P &a,const P &b)const{
return a.x!=b.x?a.x<b.x:a.y<b.y;
}
};
int turn(P a,P b,P c){
return sgn((b-a).det(c-b));
}
int main(){
int t;
cin>>t;
while(t--){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>ps[i].x>>ps[i].y;
}
s1=ps[0];
t1=ps[1];
s2=ps[2];
t2=ps[3];
vector <P> qs=convex_hull(ps,n);
n=qs.size();
bool succ=false;
if(!intersect(s1,t1,s2,t2)){
succ=true;
}
else{
int cnt=0;
for(int i=0;i<n;i++){
if(s1==qs[i])++cnt;
if(t1==qs[i])++cnt;
if(s2==qs[i])++cnt;
if(t2==qs[i])++cnt;
}
if(cnt==4){
succ=false;
}
else{
succ=true;
}
}
if(succ){
printf("POSSIBLE\n");
}
else{
printf("IMPOSSIBLE\n");
}
}
return 0;
}