dzy哥哥回来给我们上课
杜老师好帅啊qwq
重新写计算几何
struct node3{
double x,y,k;
}line[NNN];
double angle[NNN];//角度表示,用弧度制,省略单位pi
练习
POJ1269
特判就特判,不是特殊情况再求交点
POJ3907
第一道计算几何提:D
code
#include
#include
#include
#include
#include
#include
using namespace std;
#define in Read()
#define re register
const int NNN=1e6+10;
int n;
struct node{
double x,y;
friend inline double operator * (const node &a,const node &b){
return a.x*b.y-a.y*b.x;
}
}v[NNN];
double ans;
int main(){
while(scanf("%d",&n)!=EOF&&n){
for(re int i=1;i<=n;i++)scanf("%lf%lf",&v[i].x,&v[i].y);
ans=0;
for(re int i=1;i<=n;i++)ans+=v[i]*v[i%n+1];
printf("%d\n",(int)(fabs(ans)/2));
}
return 0;
}
以前的代码好丑啊,但是我懒得改了
#include
using namespace std;
#define in Read()
#define re register
#define cross xor
#define point or
const int NNN=1e4+10;
struct node1{
double x,y;
}dot[NNN];
struct node2{
double x,y;
friend inline double operator cross (const node2 &u,const node2 &v){//叉乘
return 1.0*u.x*v.y-1.0*u.y*v.x;
}
friend inline double operator point (const node2 &u,const node2 &v){//点乘
return 1.0*u.x*v.x+1.0*u.y*v.y;
}
friend inline node2 operator + (const node2 &u,const node2 &v){//向量加法
node2 ans;
ans.x=u.x+v.x;
ans.y=u.y+v.y;
return ans;
}
friend inline node2 operator - (const node2 &u,const node2 &v){//向量减法
node2 ans;
ans.x=u.x-v.x;
ans.y=u.y-v.y;
return ans;
}
}vec[NNN];
inline node2 operator - (const node1 &a,const node1 &b){//a到b的向量(a减b)注意顺序
node2 ans;
ans.x=a.x-b.x;
ans.y=a.y-b.y;
return ans;
}
inline node1 operator + (const node1 &a,const node2 &v){//已知起点和向量求终点
node1 ans;
ans.x=a.x+v.x;
ans.y=a.y+v.y;
return ans;
}
int main(){
return 0;
}
其他运算:
s i n < a ⃗ , b ⃗ > = ∣ a ⃗ × b ⃗ ∣ ∣ a ⃗ ∣ ∣ b ⃗ ∣ sin<\vec{a},\vec{b}>=\frac{|\vec{a}\times\vec{b}|}{|\vec{a}||\vec{b}|} sin<a,b>=∣a∣∣b∣∣a×b∣
每个点(向量)要通过极角排一下序
POJ3348板子题
code
#include
#define in Read()
#define re register
#define swap std::swap
#define sort std::sort
inline int in{
int i=0,f=1;char ch;
while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(ch<='9'&&ch>='0')i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
const int NNN=2000+10;
const double eps=1e-6;
int num;
struct node{
double x,y;
node(){}
node(double _x,double _y){x=_x,y=_y;}
friend node operator - (const node u,const node v){return node(u.x-v.x,u.y-v.y);}
friend node operator + (const node u,const node v){return node(u.x+v.x,u.y+v.y);}
friend node operator * (const node u,const double a){return node(u.x*a,u.y*a);}
friend node operator / (const node u,const double a){return node(u.x/a,u.y/a);}
friend double operator * (const node u,const node v){return (u.x*v.x+u.y*v.y);}
friend double operator ^ (const node u,const node v){return (u.x*v.y-u.y*v.x);}
void PRINT_VEC(){printf("%.2lf %.2lf",x,y);}
void SCAN_VEC(){scanf("%lf%lf",&x,&y);}
}vec[NNN],convec[NNN],O;
inline double dist(node u){return sqrt(u*u);}
inline double cros(node u,node v,node w){return (u-v)^(w-v);}//u←v→w
inline bool operator < (const node u,const node v){
double res=cros(u,vec[1],v);
return res==0?u.x<v.x:res>0;
}
int main(){
O.x=0,O.y=0;
int n=in,id=1;
for(re int i=1;i<=n;++i){
vec[i].SCAN_VEC();
if(vec[i].x<vec[id].x||(fabs(vec[i].x-vec[id].x)<eps&&vec[i].y<vec[id].y))id=i;
}
swap(vec[1],vec[id]);
sort(vec+2,vec+n+1);
// for(re int i=1;i<=n;++i)vec[i].PRINT_VEC(),puts("");
convec[++num]=vec[1];
for(re int i=2;i<=n;++i){
while(num>1&&cros(convec[num-1],convec[num],vec[i])>0)--num;
convec[++num]=vec[i];
}
// for(re int i=1;i<=num;++i)convec[i].PRINT_VEC(),puts("");
convec[0]=convec[num];
double res=0;
for(re int i=1;i<=num;++i)res+=cros(convec[i-1],O,convec[i]);
printf("%d",(int)res/100);
return 0;
}
看似O(N2)实际O(N)
是不是很妙?
很久以后再看代码,发现这真是一个旋转。。。
这个代码RE了,烦请各位大佬指正
//RE码,懒得改了
#include
#include
#include
#define in Read()
#define re register
#define swap std::swap
#define sort std::sort
#define max std::max
inline int in{
int i=0,f=1;char ch;
while((ch>'9'||ch<'0')&&ch!='-')ch=getchar();
if(ch=='-')f=-1,ch=getchar();
while(ch<='9'&&ch>='0')i=(i<<1)+(i<<3)+ch-48,ch=getchar();
return i*f;
}
int n,id;
const int NNN=5000+10;
const double eps=1e-6;
int num;
struct node{
double x,y;
node(){}
node(double _x,double _y){x=_x,y=_y;}
friend node operator - (const node u,const node v){return node(u.x-v.x,u.y-v.y);}
friend node operator + (const node u,const node v){return node(u.x+v.x,u.y+v.y);}
friend node operator * (const node u,const double a){return node(u.x*a,u.y*a);}
friend node operator / (const node u,const double a){return node(u.x/a,u.y/a);}
friend double operator * (const node u,const node v){return (u.x*v.x+u.y*v.y);}
friend double operator ^ (const node u,const node v){return (u.x*v.y-u.y*v.x);}
void PRINT_VEC(){printf("%.2lf %.2lf",x,y);}
void SCAN_VEC(){scanf("%lf%lf",&x,&y);}
}vec[NNN],convex[NNN],O;
inline double dist(node u){return sqrt(u*u);}
inline double cros(node u,node v,node w){return (u-v)^(w-v);}//u←v→w
inline bool operator < (const node u,const node v){
double res=cros(u,vec[1],v);
return res==0?u.x<v.x:res>0;
}
inline int nxt(int x){return x==n?1:x+1;}
inline int SOLVE(){
int res=0;
convex[n+1]=convex[1];
for(re int i=1,j=3;i<=n;++i){
while(nxt(j)!=i&&
cros(convex[i],convex[i+1],convex[j])<=cros(convex[i],convex[i+1],convex[j+1]))j=nxt(j);
res=max(res,(int)((convex[j]-convex[i])*(convex[j]-convex[i])));
res=max(res,(int)((convex[j]-convex[i+1])*(convex[j]-convex[i+1])));
}
return res;
}
int main(){
O.x=0,O.y=0;
n=in,id=1;
for(re int i=1;i<=n;++i){
vec[i].SCAN_VEC();
if(vec[i].x<vec[id].x||(fabs(vec[i].x-vec[id].x)<eps&&vec[i].y<vec[id].y))id=i;
}
swap(vec[1],vec[id]);
sort(vec+2,vec+n+1);
convex[++num]=vec[1];
for(re int i=2;i<=n;++i){
while(num>1&&cros(convex[num-1],convex[num],vec[i])>0)--num;
convex[++num]=vec[i];
}
if(num==2){
printf("%d",(int)((convex[1]-convex[2])*(convex[1]-convex[2])));
return 0;
}
int ans=SOLVE();
printf("%d",ans);
return 0;
}
处理面积交的问题
与线性规划很相似
polygon内部的所有点构成的点集叫做polygon的核
所有核的交集就是我们要求的面积
算法步骤: