• poj 1265 Area【计算几何:叉积计算多边形面积+pick定理计算多边形内点数+计算多边形边上点数】


    题目:http://poj.org/problem?id=1265

    Sample Input

    2
    4
    1 0
    0 1
    -1 0
    0 -1
    7
    5 0
    1 3
    -2 2
    -1 0
    0 -3
    -3 1
    0 -3
    

    Sample Output

    Scenario #1:
    0 4 1.0
    
    Scenario #2:
    12 16 19.0

    注意:题目给出的成对的数可不是坐标,是在x和y方向走的数量。


    边界上的格点数:一条左开右闭的线段(x1, x2)->(x2, y2)上的格点数为:gcd( abs(x2-x1), abs(y2-y1) );
    Pick公式:对于给定的坐标都是整点的简单多边形,有如下等式:
    多边形面积=多边形内部格点数+边上的格点数/2 - 1; 由此可以推出如何计算多边形内部的格点数量!
    当然这需要知道多边形的面积,计算多边形的面积:顺时针或逆时针相邻两点分别与原点构成的向量的叉积累加和,再取绝对值,再除2
    (因为顺逆方向的问题,可能会导致叉积累加和为负,又因为叉积计算的是向量围成的四边行的面积所以还要除2)

    代码:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <math.h>
    #include <iostream>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    struct node
    {
        int x;
        int y;
    }q[110];
    
    int cal_area(node a, node b)
    {
        return a.x*b.y-a.y*b.x;
    } //叉积计算两个向量的面积
    
    int gcd(int a, int b)
    {
        return b==0?a:gcd(b,a%b);
    }
    int main()
    {
        int tg; scanf("%d", &tg);
        int n;
        int i, j;
        for(int cnt=1; cnt<=tg; cnt++){
            scanf("%d", &n);
            q[0].x=0; q[0].y=0; //这是坐标原点
    
            int p_on_l=0; //point on line
    
            for(i=1; i<=n; i++){
               scanf("%d %d", &q[i].x, &q[i].y );
               //先计算线段上的点数
               int dx=abs(q[i].x);
               int dy=abs(q[i].y);
               p_on_l+=gcd(dx, dy);
    
               q[i].x+=q[i-1].x;
               q[i].y+=q[i-1].y; //题目中给出的是前一个点在x y方向上行走的数量
            }                    //只要累加就可以计算出i节点的坐标
            //所有点的坐标计算完毕
            int area=0;
            for(i=2; i<=n; i++){
                area+=cal_area(q[i], q[i-1]);
            }
            area=abs(area); //多边行的面积一定大于等于0 如果求出的结果为负值
                            //说明叉积计算的方向是和正值计算相比是反的
            double ans=area/2.0;//叉积计算的是平行四边行的面积 不是三角形 面积要减半
    
            printf("Scenario #%d:
    ", cnt);
            printf("%d %d %.1lf
    ", (area/2+1-p_on_l/2), p_on_l, ans);
            printf("
    ");
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    Asp.Net : 实现一个 DataSet 或DataTable SELECT DISTINCT (字段唯一性)
    Jquery 局部刷新及 表单取值赋值 处理返回json数据 一些基本操作
    C# 自动化模型编辑Word
    泛型集合List的添加、访问、遍历和删除
    泛型转DataTable方法
    服务器按钮如何通过js验证再触发提交事件?
    Asp.Net 无限分类生成表格 &lt;后台自定义输出table&gt;
    table的innerHTML “未知运行错误”。
    js 截取字符串的方法 C# 正则判断数字及截取字符
    Microsoft Office Visio 2007 设计数据库关系图
  • 原文地址:https://www.cnblogs.com/yspworld/p/4717309.html
Copyright © 2020-2023  润新知