UVA 10088 Trees on My Island(求整顶点多边形内部整点数)

来源:互联网 发布:淘宝优内部惠券领取 编辑:程序博客网 时间:2024/06/05 09:21

UVA 10088 Trees on My Island(求整顶点多边形内部整点数)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=12&page=show_problem&problem=1029

题意:

       给你一个顶点都是整点的多边形,要你求出该多边形内部的整点个数?

分析:

       假设多边形的面积为S, 内部的整点为A个, 边上的整点为B个. 那么由pick定理可得: A+B/2-1=S. 所以我们只要求出多边形的面积和它边上的整点个数即可.

       由于点是按顺时针或逆时针给出的,所以可以直接用刘汝佳的模板来求多边形面积(本质是把多边形分成一个个的小三角形来求面积和).

       对于多边形边上的整点: 一条由整点构成的线段(线段长度>0)它内部(不包含端点)的整点个数=gcd(线段的X增量,线段的Y增量)-1.该结论的证明在POJ2954题解中:

http://blog.csdn.net/u013480600/article/details/39269265

本题找int溢出的bug找了半天,哎.

       注意:如果需要用long long的题目还是劲量所有数据都用long long,因为你没法兼顾到每一个需要强转的int算术表达式.

AC代码:

#include<cstdio>#include<algorithm>#include<cmath>#include<iostream>using namespace std;const int maxn=1000+10;struct Point{    int x,y;    Point(){}    Point(int x,int y):x(x),y(y){}}P[maxn];typedef Point Vector;Vector operator-(Point A,Point B){    return Vector(A.x-B.x,A.y-B.y);}long long Cross(Point A,Point B){    return (long long)A.x*B.y-(long long)A.y*B.x;//严重错误,后面的(long long)忘加了}double PolygenArea(Point *p,int n){    double area=0;//错误2,area一定要是double的,如果area为int,那么/2会丢失精度    for(int i=1;i<n-1;++i)        area += Cross(p[i]-p[0], p[i+1]-p[0]);//错误1,这里不能加abs求绝对值    return fabs(area)/2;}int gcd(int a,int b){    return b==0? a : gcd(b,a%b);}int PointInLine(Point A,Point B)//整点线段AB内部的整点数{    int dx=abs(A.x-B.x),dy=abs(A.y-B.y);    if(dx==0 && dy==0) return 0;    return gcd(dx,dy)-1;}long long PointInPolygen(Point *p,int n)//整点多边形内部的整点数{    long long s=PolygenArea(p,n);    long long b=n;//在多边形边上的整点数目    for(int i=0;i<=n-1;++i)        b += PointInLine(p[i],p[(i+1)%n]);    return s-b/2+1;}int main(){    int n;    while(scanf("%d",&n)==1 && n)    {        for(int i=0;i<n;++i) scanf("%d%d",&P[i].x,&P[i].y);        printf("%lld\n",PointInPolygen(P,n));    }    return 0;}

0 0
原创粉丝点击