算法篇——果园里的树

  来源:《算法竞赛入门经典》例题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

  样例输出

  15

  17

  分析

  三角形的有向面积:

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;
}

  上面得到的是以A(x0,y0),B(x1,y1),C(x2,y2)为定点的三角形的有向面积的2倍

  如果area≥0,则说明ABC三点呈现逆时针排列;

  如果area=0,则ABC三点共线;

  如果area≤0,则说明ABC三点呈现顺时针排列。

  假设输入三角形为ABC,点O在三角形ABC内部或边界上当且仅当SABC=SOAB+SOBC+SOCA,所以我们只需遍历坐标系中所有的点判定是否在三角形内部或边界上即可。

  需要注意的是:在判断两个浮点数a和b是否相等时,请尽量判断fabs(a-b)是否小于一个极小的数(求浮点数的绝对值要用fabs,求整数绝对值用abs),如1e-9(C语言中的浮点数,表示1*10-9

  源码

#include<stdio.h>
#include<math.h>

double area2(double x0,double y0,double x1,double y1,double x2,double y2)//算出三角形有向面积的2倍
{
    return x0*y1+x2*y0+x1*y2-x2*y1-x0*y2-x1*y0;
}

int main()
{
    double x0,y0,x1,y1,x2,y2,S1,S2,S3,S;
    int x,y,n;            //n表示三角形内部和边界上树的数量
    while(scanf("%lf%lf%lf%lf%lf%lf",&x0,&y0,&x1,&y1,&x2,&y2)==6)
    {
        n=0;
        S=fabs(area2(x0,y0,x1,y1,x2,y2));
        for(x=1;x<=99;x++)
        {
            for(y=1;y<=99;y++)
            {
                S1=fabs(area2(x*1.0,y*1.0,x0,y0,x1,y1));
                S2=fabs(area2(x*1.0,y*1.0,x1,y1,x2,y2));
                S3=fabs(area2(x*1.0,y*1.0,x2,y2,x0,y0));
                if(fabs(S-S1-S2-S3)<1e-9)   //判断树是否在三角形的内部或者边界上
                    n++;
            }
        }
        printf("%d\n",n);
    }

    return 0;
}

  另外,对于上述问题有的人会想到用海伦公式:   ,       来计算,但在使用时需要小心浮点误差(前面的area2只有加减法和乘法,而海伦公式中却有除法和开平方)。

  如果三角形的三个点A,B,C是按照统一方向(顺时针或逆时针)输入的话,我们还可以根据有向面积SOAB,SOBC和SOCA的符号判断O是否在在三角形内部或边界上(三个三角形的有向面积互不异号)。

时间: 2024-08-05 02:22:18

算法篇——果园里的树的相关文章

白书 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

算法第十八章 B树

一.高级数据结构 本章以后到第21章(并查集)隶属于高级数据结构的内容.前面还留了两章:贪心算法和摊还分析,打算后面再来补充.之前的章节讨论的支持动态数据集上的操作,如查找.插入.删除等都是基于简单的线性表.链表和树等结构,本章以后的部分在原来更高的层次上来讨论这些操作,更高的层次意味着更复杂的结构,但更低的时间复杂度(包括摊还时间). B树是为磁盘存储还专门设计的平衡查找树.因为磁盘操作的速度要远远慢于内存,所以度量B树的性能,不仅要考虑动态集合操作消耗了多少计算时间,还要考虑这些操作执行了多

深度学习word2vec笔记之算法篇

深度学习word2vec笔记之算法篇 声明:  本文转自推酷中的一篇博文http://www.tuicool.com/articles/fmuyamf,若有错误望海涵 前言 在看word2vec的资料的时候,经常会被叫去看那几篇论文,而那几篇论文也没有系统地说明word2vec的具体原理和算法,所以老衲就斗胆整理了一个笔记,希望能帮助各位尽快理解word2vec的基本原理,避免浪费时间. 当然如果已经了解了,就随便看看得了. 一. CBOW加层次的网络结构与使用说明 Word2vec总共有两种类

算法导论:Trie字典树

1. 概述 Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. Trie一词来自retrieve,发音为/tri:/ “tree”,也有人读为/tra?/ “try”. Trie树可以利用字符串的公共前缀来节约存储空间.如下图所示,该trie树用10个节点保存了6个字符串pool.prize.preview.prepare.produce.progress 在该trie树中,字符串preview,prepa

算法5-1:平衡查找树之二三树

平衡查找树的目标是实现查找.插入.删除操作在最坏情况下的复杂度均为logN. 本节将介绍二三查找树. 二三树中有两种节点: 二节点对应一个键,有两个子节点 三节点对应两个键,有三个子节点 二三查找树非常平衡,每个空节点到根节点的距离都是一样的 . 查找操作 在二三树中查找一个键的时候有以下规则: 如果是二节点,二节点对应1个值,如果要查找的值比该节点对应的值小,就往左侧深入,反之亦成 如果是三节点,三节点对应2个值,如果比两个值都小,就往左侧深入,如果介于两个值之间,就往中间深入,如果比两个值都

数据挖掘十大经典算法--CART: 分类与回归树

一.决策树的类型  在数据挖掘中,决策树主要有两种类型: 分类树 的输出是样本的类标. 回归树 的输出是一个实数 (比如房子的价格,病人呆在医院的时间等). 术语分类和回归树 (CART) 包括了上述两种决策树, 最先由Breiman 等提出.分类树和回归树有些共同点和不同点-比如处理在何处分裂的问题. 分类回归树(CART,Classification And Regression Tree)也属于一种决策树,之前我们介绍了基于ID3和C4.5算法的决策树. 这里仅仅介绍CART是如何用于分类

大叔也说Xamarin~Android篇~ListView里的Click事件并获取本行的其它元素

原文:大叔也说Xamarin~Android篇~ListView里的Click事件并获取本行的其它元素 我原创,我贡献,我是仓储大叔 本篇大叔原创,本着对技术的热爱去研究它,把成果分享给国人!大叔始终相信一句话:你只有选择一个感兴趣的工作,你才能更好的发挥你的潜力,而这一切都建立在你不断研究,不断钻研的前提下. Xamarin文章在网上比较少,而ListView相关的信息更好,有限的那么几个还都说的不清楚,只是告诉大家如何去完成按钮的事件,而在事件里,如何获取当前行的其它元素信息则没有说明,在网

解剖SQLSERVER 第五篇 OrcaMDF里读取Bits类型数据(译)

原文:解剖SQLSERVER 第五篇 OrcaMDF里读取Bits类型数据(译) 解剖SQLSERVER 第五篇  OrcaMDF里读取Bits类型数据(译) http://improve.dk/reading-bits-in-orcamdf/ Bits类型的存储跟SQLSERVER其他定长数据类型的存储很不一样.通常,所有定长列都会显示出来,一个条记录里定长数据部分的字段数据总是一个挨着一个 我们可以写入磁盘的最小数据单位是一个字节,存储位类型数据的天真的方法就是使用一整个(字节@)来存储每一

解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)

解剖SQLSERVER 第四篇  OrcaMDF里对dates类型数据的解析(译) http://improve.dk/parsing-dates-in-orcamdf/ 在SQLSERVER里面有几种不同的date相关类型,当前OrcaMDF 支持三种最常用的date类型:date,datetime,smalldatetime SqlDate实现 date 类型在三种类型之中是最简单的,他是一个3个字节的定长类型,存储了日期值它支持的日期范围从0001-01-01到9999-12-31 默认值