TYVJ计算几何

绳子围点

链接网址:http://tyvj.cn/Problem_Show.asp?id=1150

先求凸包,再求面积,再用欧几里德算法求边界上的点数,然后用pick定理。

---------------------------------------------PICK 定理;
S=I+(A/2)-1;
s是面积,I是多边形内部整点,A是边上整点;
A 用GCD求。
既得解。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int MAX=200010;
struct Point
{   __int64 x,y;
    bool operator<(const Point &P) const//坐标排序 
    {   return y<P.y||(y==P.y&&x<P.x);
    } 
};
Point P[MAX],res[MAX];
__int64 Gcd(__int64 n,__int64 m)//求最大公约数 
{   return m==0?n:Gcd(m,n%m);
}
__int64 multi(Point P0,Point P1,Point P2)//求叉积 
{   return (P1.x-P0.x)*(P2.y-P0.y)>(P2.x-P0.x)*(P1.y-P0.y);
} 
__int64 Graph(__int64 n)//凸包 
{   __int64 top=1;   
    sort(P,P+n);  
    if(n==0) return 0; res[0]=P[0];  
    if(n==1) return 1; res[1]=P[1];  
    if(n==2) return 2; res[2]=P[2];  
    for(int i=2;i<n;i++)  
    {   while(top && multi(P[i],res[top],res[top-1])) top--;  
        res[++top]=P[i];  
    }    
    __int64 len=top;  
    res[++top]=P[n-2];  
    for(int i=n-3;i>=0;i--)  
    {   while(top!=len && multi(P[i],res[top],res[top-1])) top--;  
        res[++top]=P[i];  
    }  
    return top;  
}  
__int64 Area(__int64 n)//求面积   
{   __int64 area=0;  
    for(int i=1;i<=n;i++)  
        area+=res[i-1].x*res[i%n].y-res[i%n].x*res[i-1].y;
    return area>0?area:-area;       
}  
__int64 Count(__int64 n)    
{   __int64 sum=0;  
    for(int i=1;i<=n;i++)  
    {   int dx=abs(res[i%n].x-res[i-1].x);  
        int dy=abs(res[i%n].y-res[i-1].y);   
        sum+=Gcd(dx,dy);      
    }  
    return sum;      
} 
int main()
{   int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++)
        scanf("%I64d%I64d",&P[i].x,&P[i].y);  
    __int64 len=Graph(n);    
    __int64 I=(Area(len)-Count(len))/2+1;//pick定理 
    printf("%I64d\n",I+Count(len));     
    return 0;
}


神秘大三角

链接网址:http://tyvj.cn/Problem_Show.asp?id=1523

利用叉积来判断

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
char a[10][10];
struct point
{
       double x,y;
};

typedef  point  triangle[3]; 

double triangle_area(triangle t)//求三角形面积 
{   return  fabs(t[0].x*t[1].y+t[1].x*t[2].y+t[2].x*t[0].y
                  -t[1].x*t[0].y-t[2].x*t[1].y-t[0].x*t[2].y)/2;
}

int multi(point a,point b,point c)
{
        return ((a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y));
}

int is_in_triangle(point p,triangle t)
{  double k1,k2,k3;
    k1=multi(t[0],t[1],p);
    k2=multi(t[1],t[2],p);
    k3=multi(t[2],t[0],p);
    //cout<<k1<<" "<<k2<<" "<<k3<<endl;
    if(k1*k2*k3==0) 
    {
       if(k1*k2==0 && k1*k3==0 && k2*k3==0) return 4;
       else if(k1*k2<0 || k1*k3<0 || k2*k3<0)return 2;
            else return 3;
    }
    if (k1*k2*k3!=0)
    {   
        if ( k1*k2<0 ){ return 2;}
        if ( k1*k3<0 ){ return 2;}
    }
    return 1;    
}


int main()
{
    int i;
    point p[10];
    triangle t; 
    while(cin>>a[0]>>a[1]>>a[2]>>a[3]){
        //getchar(); 
        for(i=0;i<4;i++)
           sscanf(a[i],"(%lf,%lf)",&p[i].x,&p[i].y);
        for(i=0;i<3;i++){
           t[i].x=p[i].x;
           t[i].y=p[i].y;
        } 
        cout<<is_in_triangle(p[3],t)<<endl; 
       
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值