Chain Code [UVALive - 4884] Pick定理和多边形求面积

一句话题意:

0-7八个数字表示8个方向,给你一串表示方向的数字,问按这种走法围成的多边形里面包含几个像素(保证是一个多边形)。


分析:

这题一看毫无头绪,甚至想上扫描线线段树…
后来问同学,才恍然大悟。
pick定理+多边形求面积

  • Pick定理
    什么是pick定理呢?
    pick定理是对于点阵图来说的。
    一个公式:2S = 2 * a + b - 2。
    其中S表示像素围成的点阵图的面积,a 表示点阵图除边界外内部的像素个数,b 表示边界的像素个数。
    举个栗子。(图是百度偷的)
    这里写图片描述
    拿下面的那个较小的三角形来说吧
    对于这个三角形,其边界在格点上有四个点,内部没有完整的点。
    即a = 0, b = 4.
    他的面积可以表示为:2S = 2 * 0 + 4 - 2 = 2,即s = 1。
    我们可以简单的通过三角形面积公式得到s = 2 * 1 / 2 = 1。
    与实际情况吻合。

好了pick定理现在我们理解了,那么在这个题中是怎么运用的呢?
我们发现,对于 b ,也就是边界点的个数,我们是已知的,他的大小就等于字符串的长度。
内部的点与面积是未知的。
怎么求呢?
就是求多边形面积啦。

  • 多边形求面积
    再上图。
    这里写图片描述
    对于一个 n 边形,我们可以把它分为 n - 2 个三角形。
    对于每个三角形,我们可以通过向量得到面积。
    那么把多边形分解成多个三角形,就可以求出多边形的总面积了

好了,知道了多边形面积,和边界的像素个数,就可以求出内部的点的个数了。
那么答案就是 边界的点的个数+内部点的个数。


AC代码

#include <bits/stdc++.h>

using namespace std;

const int inf = 0x3f3f3f3f;
int dirx[8] = {0, -1, -1, -1, 0, 1, 1, 1};
int diry[8] = {1, 1, 0, -1, -1, -1, 0, 1};

int main()
{
    string s;
    long long x = 0, y = 0, area = 0;
    while (cin >> s)
    {
        x = y = area = 0;
        long long len = s.size();
        for (int i = 0; i < s.size(); i++)
        {
            int dir = s[i] - '0';
            long long tx = x + dirx[dir];
            long long ty = y + diry[dir];
            //tx和ty表示从第0个点到当前点的向量
            //x和y表示从第0个点到当前点的上一个点的向量
            area += x * ty - y * tx;
            //area是2S的值,也就是每次求的不是三角形的面积,而是平行四边形的面积
            x = tx;
            y = ty;
        }
        area = abs(area);//面积最后求出来会有正有负,只需要得到他们的绝对值即可
        cout << (area + len) / 2 + 1 << endl;//Pick定理
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值