UVa-143-Orchard Trees(果樹林)[計算幾何]

Problem
問題

An Orchardist has planted an orchard in a rectangle with trees uniformly spaced in both directions. Thus the trees form a rectangular grid and we can consider the trees to have integer coordinates. The origin of the coordinate system is at the bottom left of the following diagram:
有一個果園主種植了一片矩形的果樹林,果樹之間的間隔距離在縱橫兩個方向都相同。想象這片果樹林形成了一個矩形的格網,每棵果樹的縱橫座標值均爲整數。座標系統的原點定在下圖的左下角:

 

142-1

 

Consider that we now overlay a series of triangles on to this grid. The vertices of the triangle can have any real coordinates in the range 0.0 to 100.0, thus trees can have coordinates in the range 1 to 99. Two possible triangles are shown.
我們現在要在這個格網上面放上一些三角形。三角形的頂點可以是0.0到100.0之間的任意實數,這樣樹的橫縱座標就限定在1到99之間。上圖顯示了兩個可能三角形。

Write a program that will determine how many trees are contained within a given triangle. For the purposes of this problem, you may assume that the trees are of point size, and that any tree (point) lying exactly on the border of a triangle is considered to be in the triangle.
寫一個程序計算出在給定的一個三角形內有多少樹。爲簡化題目,你可以認爲樹都一個無窮小的點,而精確位於三角形邊上的樹應算作在三角形內的。

 

Input and Output
輸入和輸出

Input will consist of a series of lines. Each line will contain 6 real numbers in the range 0.00 to 100.00 representing the coordinates of a triangle. The entire file will be terminated by a line containing 6 zeroes (0 0 0 0 0 0).
輸入由多行組成,每行包含6個範圍在0.00到100.00之間的整數值,分別代表三角形的三個頂點座標的x,y。全部的輸入由6個0(0 0 0 0 0 0)表示結束。

Output will consist of one line for each triangle, containing the number of trees for that triangle right justified in a field of width 4.
每個輸入的三角形對應一行輸出,打印出在該三角形內部的樹的數量。輸出的數字應右對齊至第4列。

 

Sample input
輸入示例

1.5 1.5  1.5 6.8  6.8 1.5
10.7 6.9  8.5 1.5  14.5 1.5
0 0 0 0 0 0

 

Sample output
輸出示例

15
17

思路:這個題目其實不難,看懂題意之後就可以知道,就是要判斷有多少個點在三角形內。

具體判斷過程:

如果點K在三角形內就可以發現點k連接三角形三個頂點把三角形分成三個三角形,其面積和就是大三角形面積和。

所以如果點在三角形內那麼,就有dcmp(sabc-(sabk+sack+scbk))==0。這道題要注意的是,當你遍歷的時候,選擇三個頂點中的最大最小X,最大最小Y,遍歷這個矩形中的點就可以了,但是最大的X和Y不可以超過99,最小的X和Y不能小於1(題目要求),所以要對最小往上取整,最大往下取整。

#include<iostream>
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
using namespace std;
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define eps 1e-10

int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}

struct point
{
    double x,y;
}p[30];//點


double s(point a,point b,point c)
{
    double bax = b.x-a.x;
    double bay = b.y-a.y;
    double cax = c.x-a.x;
    double cay = c.y-a.y;
    return fabs(bax*cay-bay*cax);
}

int judge(point k)
{
    double sabc,sabk,sack,scbk;
    sabc=s(p[0],p[1],p[2]);
    sabk=s(k,p[0],p[1]);
    sack=s(k,p[0],p[2]);
    scbk=s(k,p[1],p[2]);
    if(dcmp(sabc-(sabk+sack+scbk))==0)
        return 1;
    else return 0;
}

int main()
{
    double x1,x2,x3,y1,y3,y2;
    while(scanf("%lf %lf %lf %lf %lf %lf",&x1,&y1,&x2,&y2,&x3,&y3))
    {
        if(!x1&&!x2&&!x3&&!y1&&!y2&&!y3) break;
        //cout<<313132<<endl;
        p[0].x=x1,p[0].y=y1;
        p[1].x=x2,p[1].y=y2;
        p[2].x=x3,p[2].y=y3;
       // int X,X1,Y,Y1;
        int X1= max(1, ceil(min(x1, min(x2, x3))));//求出最大最小xy
        int X = min(99, (int)max(x1, max(x2,x3)));
        int Y1 = max(1, ceil(min(y1, min(y2, y3))));
        int Y = min(99, (int)max(y1, max(y2, y3)));

        int sum=0;
        point k;
        for(double i=X1;i<=X;i++)
        {
            for(double j=Y1;j<=Y;j++)
            {
                k.x=i,k.y=j;
                if(judge(k))
                sum++;
            }
        }
       printf("%4d\n",sum);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章