poj2954 Triangle【Pick定理】

题目大意:

给你一个由3个整点构成的三角形,要你求出该三角形内部的整点个数.

解题思路:

用了一个非常神奇的小定理:Pick定理。
由Pick定理,一个多边形如果每个顶点都由整点构成,该多边形的面积为S,该多边形边上的整点为L,内部的整点为N,则有:2S=2N+L-2。
那么我们要求的N即为(2S+2-L)/2。

S可由向量叉积得到,关键是求三角形各边上有多少个整点。
假设有一条由两个整点构成的线段,该线段该线段X方向的增量绝对值为DX, Y方向的增量绝对值为DY. 设线段内部(不含端点)整点个数为ans:
DX=DY=0时, ans=0
DX=0时, ans=DY-1(等价于gcd(DX,DY)-1 )
DY=0时, ans=DX-1 (等价于gcd(DX,DY)-1 )
DX!=0且DY!=0时, ans=gcd(DX,DY)-1

PS:poj编译器太老了,bits不能用,读入优化也会出问题。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#define ll long long
using namespace std;

const int N=100005;
struct point
{
    int x,y;
    point(){}
    point(int _x,int _y):x(_x),y(_y){}
    inline friend point operator - (const point &a,const point &b)
    {return point(a.x-b.x,a.y-b.y);}
    inline friend int operator * (const point &a,const point &b)
    {return a.x*b.y-a.y*b.x;}
};

int gcd(int a,int b)
{
    return b?gcd(b,a%b):a;
}

int calc(point a)
{
    if(!a.x&&!a.y)return 0;
    return gcd(abs(a.x),abs(a.y))-1;
}

int main()
{
    //freopen("lx.in","r",stdin);
    point a,b,c;
    while(scanf("%d%d%d%d%d%d",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y))
    {
        if(!a.x&&!a.y&&!b.x&&!b.y&&!c.x&&!c.y)break;
        int S=abs((c-a)*(b-a));
        int num=calc(a-b)+calc(a-c)+calc(b-c)+3;
        cout<<(S+2-num)/2<<'\n';
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值