HDOJ 1705/POJ 2954 叉积+Pick定理

题目链接
题意:
已知一个格点三角形的三个点,问其内部的格点数目。

因坐标范围较大,此题初看很难下手。
但其实就考了一个对Pick定理的应用。

Pick定理:
对于顶点坐标均为整数的简单多边形,皮克定理说明了其面积S和内部格点数目n,边上格点数目s的关系:
S = n + s 2 − 1 S = n + \frac{s}{2} - 1 S=n+2s1

对于此题,n就是我们需要求解的量,移项得:
n = S + 1 − s 2 n = S + 1 - \frac{s}{2} n=S+12s

面积可以直接用叉积求解。
边上格点数目可以利用GCD,因数据保证三角形存在,故无需特判
a = = 0   a n d   b = = 0 a == 0 \space and \space b==0 a==0 and b==0的情况。

代码:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
typedef long long ll;

const int A = 5;
int x[A],y[A];

int gcd(int a,int b){
    if(b == 0) return a;
    return gcd(b,a%b);
}

int get_S(){return abs((x[2]-x[1])*(y[3]-y[1]) - (x[3]-x[1])*(y[2]-y[1]))/2;}

int get_num(int i,int j){
    int a = abs(x[i] - x[j]);
    int b = abs(y[i] - y[j]);
    return gcd(a,b) - 1;
}

int main(){
    while(~scanf("%d%d",&x[1],&y[1])){
        for(int i=2 ;i<=3 ;i++) scanf("%d%d",&x[i],&y[i]);
        bool flag = 1;
        for(int i=1 ;i<=3 ;i++) if(x[i]||y[i]) flag = 0;
        if(flag) break;

        int S = get_S();
        int s = 3 + get_num(1,2) + get_num(2,3) + get_num(1,3);
        printf("%d\n",S+1-(s/2));
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值