5.4.3 果园里的树

果园里的树排列成矩阵。他们的x和y的坐标均是1~99的整数。输入若干个三角形,依次统计每个三角形内部和边界上共有多少棵树。

输入:

1.5  1.5       1.5  6.8      6.8  1.5

10.7  6.9     8.5  1.5      14.5  1.5

此题用三角形有向面积来解,求有向面积2倍的函数为:

double area(double x0,double y0,double x1,double y1,double x2,double,y2)
{
    return x0*y1+x2*y0+x1*y2-x0*y2-x1*y0-x2*y1;
}

若求其面积,即没有方向的:则为fabs(S)/2;

可以用行列式来记住这个式子:

  |x0  y0  1|

2S=|x1  y1  1|=x0*y1+x2*y0+x1*y2-x2*y1-x0*y2-x1*y0;          

  |x2  y2  1|                           

若三角形三个点按逆时针排列,则有向面积为正,否则为负。

对一个三角形ABC和平面上任意一点O:都有            Sabc=Soab+Sobc+Soca;      

判断点p是否在三角形内部或者是边界上的方法是:O点分出的三个三角形按oab,obc,oca的顺序得到的结果与原来的大三角形Sabc的同号或为0。

简单代码如下:

 1 #include <stdio.h>
 2 #include <math.h>
 3 #include <string.h>
 4 #include <stdlib.h>
 5 #include <string.h>
 6 #include <iostream>
 7 #include <algorithm>
 8 using namespace std;
 9 
10 const double eps = 1e-9;
11 double area2(double x0, double y0, double x1, double y1, double x2, double y2){
12     return fabs(x0 * y1 + x2 * y0 + x1 * y2 - x2* y1 - x0 * y2 - x1 * y0);
13 }
14 int main(){
15     int i, j, t, n, m;
16     int ans;
17     double x0, x1, x2, y0, y1, y2;
18     while(EOF != scanf("%lf%lf%lf%lf%lf%lf",&x0, &y0, &x1, &y1, &x2, &y2)){
19         ans = 0;
20         double area = area2(x0, y0, x1, y1, x2, y2);
21         for(i = 1; i < 100; ++i){
22             for(j = 1; j < 100; ++j){
23                 double area0 = area2(i, j, x0, y0, x1, y1) + area2(i, j, x1, y1, x2, y2) + area2(i, j, x2, y2, x0, y0);
24                 if(fabs(area0 - area) < eps)    ++ans;
25             }
26         }
27         printf("%d\n",ans);
28     }
29     return 0;
30 }

注意,如果area2函数写成

double area2(double x0, double y0, double x1, double y1, double x2, double y2){
    return x0 * y1 + x2 * y0 + x1 * y2 - x2* y1 - x0 * y2 - x1 * y0;
}

则会WA。

posted @ 2014-07-07 13:16  Jeremy Wu  阅读(191)  评论(0编辑  收藏  举报