1. 程式人生 > >計蒜客(三角形的內點)

計蒜客(三角形的內點)

lse alt 輸入 正方 分隔 width one -m amp

在一個平面坐標系中,我們可以選出三個不全在一條線上的點構成一個三角形。我們稱一個在三角形內(不包含三角形的邊上),橫縱坐標皆為整數的點位這個三角形的內點。 對於一個由(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的關系: 技術分享圖片
(其中n表示多邊形內部的點數,s表示多邊形邊界上的點數,S表示多邊形的面積) 所有判斷邊上有多上個整點,內部有多少個整點,底*高 算出三角形面積 我們還要判定是否為整,就是與一個無限趨近於0的數相比就OK了 技術分享圖片
#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; }
View Code

計蒜客(三角形的內點)