计蒜客(三角形的内点)
在一个平面坐标系中,我们可以选出三个不全在一条线上的点构成一个三角形。我们称一个在三角形内(不包含三角形的边上),横纵坐标皆为整数的点位这个三角形的内点。 对于一个由(0,0)、(n,m)、(p,0)作为顶点构成的三角形,请你设计程序求出他的内点数。
输入包括一行,包括三个用空格分隔的整数,分别为n,m,p(0 ≤ n < 32000,0 < m < 32000,0 < p < 32000)。
输出仅一个数,为这个三角形的内点的个数。
样例输入
7 5 10
样例输出
20
idea:皮克定理,我百度找到解释
这个公式是皮克(Pick)在1899年给出的,被称为“皮克定理”,这是一个实用而有趣的定理。
给定顶点坐标均是整点(或正方形格点)的简单多边形,皮克定理说明了其面积S和内部格点数目n、边上格点数目s的关系:
![](https://gss1.bdstatic.com/9vo3dSag_xI4khGkpoWK1HF6hhy/baike/s%3D88/sign=3f85e42dab773912c0268869f919a25e/342ac65c10385343327425b19113b07ecb8088e3.jpg)
(其中n表示多边形内部的点数,s表示多边形边界上的点数,S表示多边形的面积)
所有判断边上有多上个整点,内部有多少个整点,底*高 算出三角形面积
我们还要判定是否为整,就是与一个无限趋近于0的数相比就OK了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cmath> using namespace std; int square=0, ans=0, sites=0; int n, m, p; bool f(int i) { double s; double y=(double)m/(double)n; s=y*i; if((fabs(s-(int)s)<1e-8)) return true; return false; } bool h(int i) { double s; double y; if(p>n) { y=(double)m/(double)(p-n); s=y*(i-p)*(-1); } else { y=(double)m/double(n-p); s=y*(i-p); } //else //s=s=y*(i-p)*(-1); if((fabs(s-(int)s)<1e-8)) return true; return false; } int main() { cin >> n >> m >> p; square = m*p/2; sites += p+2; if(n!=0&&n!=p) { for(int i=1;i<n;i++) { if(f(i)) { sites++; } } if(p>n) { for(int i=n+1;i<p;i++) { if(h(i)) { sites++; } } } else { for(int i=p+1;i<n;i++) { if(h(i)) { sites++; } } } } else if(n==0) { sites+=m-1; if(p>n) { for(int i=n+1;i<p;i++) { if(h(i)) { sites++; } } } else { for(int i=p+1;i<n;i++) { if(h(i)) { sites++; } } } } else if(n==p) { sites+=m-1; for(int i=1;i<n;i++) { if(f(i)) { sites++; } } } if(sites%2==0) cout << square + 1 - sites/2; else cout << square + 1 - (sites-1)/2; }