# [题集]计算几何

n<=500

### 2

• 你要选择一个子集，其中每个点有 pi 的概率在子集中
• 求凸包面积的期望

𝑛 ≤ 10^3

### 3

• 求最多能选出多少个其中的点，使得这些点两两之间的连线不和

𝑛 ≤ 2000

https://www.lydsy.com/JudgeOnline/problem.php?id=4660

### 4

n<=100

bzoj3778共鸣

#include<bits/stdc++.h>
#define reg register int
#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<<endl
#define pii pair<int,int>
using namespace std;
typedef long long ll;
template<class T>il void rd(T &x){
char ch;x=0;bool fl=false;while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
for(x=numb;isdigit(ch=getchar());x=x*10+numb);(fl==true)&&(x=-x);}
template<class T>il void output(T x){if(x/10)output(x/10);putchar(x%10+'0');}
template<class T>il void ot(T x){if(x<0) putchar('-'),x=-x;output(x);putchar(' ');}
template<class T>il void prt(T a[],int st,int nd){for(reg i=st;i<=nd;++i) ot(a[i]);putchar('\n');}
namespace Modulo{
const int mod=998244353;
int mul(int x,int y){return (ll)x*y%mod;}
void inc2(int &x,int y){x=mul(x,y);}
int qm(int x,int y=mod-2){int ret=1;while(y){if(y&1) ret=mul(x,ret);x=mul(x,x);y>>=1;}return ret;}
}
//using namespace Modulo;
namespace Miracle{
const int N=105;
const int inf=0x3f3f3f3f;
int n,m;
struct po{
int x,y;
po(){}
po(int xx,int yy){x=xx;y=yy;}
po friend operator +(po a,po b){
return po(a.x+b.x,a.y+b.y);
}
po friend operator -(po a,po b){
return po(a.x-b.x,a.y-b.y);
}
int friend operator *(po a,po b){
return a.x*b.y-a.y*b.x;
}
}a[N],b[N],st[N],no[N],std;
int ca,cb;
bool smal(po a,po b){
return atan2(a.y-std.y,a.x-std.x)<atan2(b.y-std.y,b.x-std.x);
}
bool cmp(po a,po b){
double d1=atan2(a.y-std.y,a.x-std.x),d2=atan2(b.y-std.y,b.x-std.x);
if(d1!=d2) return d1<d2;
return max(a.x,a.y)<max(b.x,b.y);
}
int f[N][N],ok[N][N];
int ans;
void sol(int now){
ca=cb=0;
for(reg i=1;i<=n;++i){
if(i==now) continue;
if(a[i].x>std.x||(a[i].x==std.x&&a[i].y>=std.y)) st[++ca]=a[i];
}
for(reg i=1;i<=m;++i){
if(b[i].x>std.x||(b[i].x==std.x&&b[i].y>=std.y)) no[++cb]=b[i];
}
sort(st+1,st+ca+1,cmp);sort(no+1,no+cb+1,cmp);
for(reg i=1;i<=ca;++i){
int be=0;
while(be<cb&&smal(no[be+1],st[i])) ++be;
int ptr=be;
for(reg j=i+1;j<=ca;++j){
ok[i][j]=0;
while(ptr<cb&&!smal(st[j],no[ptr+1])) ++ptr;
for(reg k=be+1;k<=ptr;++k){
int sz=(st[i]-no[k])*(st[j]-no[k]);
if(sz>=0){
ok[i][j]=-1;
}
}
}
}
memset(f,-inf,sizeof f);
for(reg i=1;i<=ca;++i){
for(reg j=i+1;j<=ca;++j){
if(ok[i][j]!=-1){
f[i][j]=max(f[i][j],(st[i]-std)*(st[j]-std));
}
for(reg k=j+1;k<=ca;++k){
if(ok[j][k]!=-1&&(st[j]-st[i])*(st[k]-st[i])>=0){
f[j][k]=max(f[j][k],f[i][j]+(st[j]-std)*(st[k]-std));
}
}
ans=max(ans,f[i][j]);
}
}
}
int main(){
rd(n);rd(m);
for(reg i=1;i<=n;++i) rd(a[i].x),rd(a[i].y);
for(reg i=1;i<=m;++i) rd(b[i].x),rd(b[i].y);
for(reg i=1;i<=n;++i){
std=a[i];
sol(i);
}
printf("%.2lf",(double)ans/2.0);
return 0;
}

}
signed main(){
Miracle::main();
return 0;
}

/*
Author: *Miracle*
*/
View Code

n<=50

### 6

𝑛 ≤ 100, |𝑥|, |𝑦| ≤ 10^5

posted @ 2019-05-21 17:59  *Miracle*  阅读(298)  评论(0编辑  收藏  举报