牛客网 多校3 I三角形(皮克定理)

链接:https://www.nowcoder.com/acm/contest/75/I
来源:牛客网


时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
 


给你一个三角形的顶点A,B,C的坐标(坐标都为整数),请求出三角形的面积,三角形内的点的个数以及边AB、BC和AC边上的点的个数(不包括顶点ABC)


输入描述:


多组输入
每组输入三行,每行两个整数
第一行顶点A的坐标Xa,Ya.
第二行顶点B的坐标Xb,Yb.
第三行顶点C的坐标Xc,Yc.
0<=X,Y<=1,000,000
输入-1结束输入
输出描述:


每组输出一行,输出一个实数(保留一位小数),四个整数,分别代表三角形面积,三角形内的点的个数以及边AB、BC和AC边上的点的个数,每个数用空格隔开。
题意:中文题。


思路:
这里需要用到皮克定理,它是算点阵中顶点在格点上的多边形面积。
公式为2s=2a+b-2,其中a为多边形内部的点数,b表示多边形边界上的点数,s表示多边形的面积。
而gcd(dx,dy)可以算出该条边上除底部端点的所有在格点上的点数(dx=fabs(x1-x2),dy=fabs(y1-y2))。至于这个怎么来的,我不会证明。。
所以只要把三条边的gcd(dx,dy)加在一起就能得到在边上的格点数。
对于s可以用叉积来算,S=fabs(x1*y2-x2*y1)/2.


代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
ll x[5],y[5];
ll gcd(ll x,ll y)
{
    if(y==0)
        return x;
    return gcd(y,x%y);
}
int main()
{
    while(~scanf("%lld",&x[0])&&x[0]!=-1)
    {
        scanf("%lld",&y[0]);
        for(int i=1;i<=2;i++)
            scanf("%lld%lld",&x[i],&y[i]);
        ll a,b,c,d;
        double s=fabs((x[1]-x[0])*(y[2]-y[0])-(x[2]-x[0])*(y[1]-y[0]))/2;
        a=gcd(fabs(x[0]-x[1]),fabs(y[0]-y[1]))-1;
        b=gcd(fabs(x[1]-x[2]),fabs(y[1]-y[2]))-1;
        c=gcd(fabs(x[2]-x[0]),fabs(y[2]-y[0]))-1;
        d=(ll)(s-(a+b+c+3)/2+1);
        printf("%.1lf %lld %lld %lld %lld\n",s,d,a,b,c);
    }
    return 0;
}





 
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值