链接: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.
代码:
来源:牛客网
时间限制: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;
}