1. 程式人生 > >PICK定理與三角剖分

PICK定理與三角剖分

//PICK定理:S=I+E/2-1,a多邊形內部的點數,b多邊形邊界上的點數,S多邊形的面積
#include <bits/stdc++.h>
using namespace std;
struct node{int x,y;}p[200];
int n,S,E,I;//N個點,面積,邊上點數,內部點烽
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}//求A,B的GCD
int main(){
    int T,ks=1;scanf("%d",&T);      //輸入案例數
    while(T--){                     //遍歷
        //首先輸入
        int x,y;                    //定義變數讀值
        scanf("%d",&n);             //N個點
        p[0].x=0,p[0].y=0;          //賦值
        for(int i=0; i<n; i++){     //遍歷
            scanf("%d%d",&x,&y);    //輸入
            p[(i+1)%n].x=p[i].x+x;  //求出X座標的字首和,方便後面求差
            p[(i+1)%n].y=p[i].y+y;  //求出Y座標的字首和,方便後面求差
        }
        //1求邊上點數E
        for(int i=0;i<n;i++)//遍歷求鄰點間的XY座標差的最大公約數就是邊上的點
            E+=gcd(abs(p[i].x-p[(i+1)%n].x),abs(p[i].y-p[(i+1)%n].y));//累加得邊上點數
        //2求多邊形面積S:三角剖分
        for(int i=0;i<n;i++)//遍歷N個點
            S+=(p[(i+1)%n].y)*(p[i].x-p[(i+2)%n].x);//然後用叉乘累加面積
        if(S<0)S=-S;//如果是負數就取反,S是面積,注意叉乘的面積是平行四邊形
        //3求內部點數I
        I=(2*S-E+2)/2;// S/2才是三角形面積和,即簡單多邊形面積
        //最後輸出
        printf("Scenario #%d:\n",ks++);//第KS個樣例
        printf("%d %d %.1f\n\n",I,E,S/2.0);//內部點數,外部點數,多邊形面積
    }   //檢驗:內部點數+外部點數一半-1=多邊形面積
    return 0;
}