绳子围点
链接网址: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;
}