皮克定理和多边形面积及应用

皮克定理和多边形面积及应用欢迎关注更多精彩 关注我 学习常用算法与数据结构 一题多解 降维打击 皮克定理 皮克定理 皮克定理是指一个计算所有顶点坐标为整数的多边形面积公 该公式可以表示为 S a b 2 1 其中 a 表示多边形内部的坐标为整数的点数 b 表示多边形边上且坐标为整数的点数

大家好,我是讯享网,很高兴认识大家。

皮克定理

皮克定理:皮克定理是指一个计算所有顶点坐标为整数的多边形面积公。该公式可以表示为S=a+b÷2-1,其中a表示多边形内部的坐标为整数的点数,b表示多边形边上且坐标为整数的点数,S表示多边形的面积。

举个简单的例子。
在这里插入图片描述
讯享网
上图中,边上的整格点数量b=12, 内部点数量a = 4
那么三角形面积S = 4+12/2-1 = 9

多边形面积算法

对于多边,可以任选一个点O,然后把多边形顶点按照逆时针排序,遍历所有点和后一个点与O连成一个三角形,计算出所有三角形面积,并求和即可。
在这里插入图片描述
如上图所示,绿线为多边形,通过分割成多个三角形来计算面积。
计算面积时利用向量叉乘即可。
这个算法对于非凸多边形也适用。

面积公式应用

http://poj.org/problem?id=1654

题目大意

一个多边形起点从0点出发,每次沿8个方向中的1个方向,行走不超过1个格子。求最后合围区域面积。

代码

需要用c++提交
需要用c++提交
需要用c++提交

#include<stdio.h> #include<cmath> #include <algorithm> #include <vector> using namespace std; int gcd(int a, int b) { 
    if (a < 0 || b < 0)return gcd(abs(a), abs(b)); if (a > b)return gcd(b, a); if (a == 0)return b; return gcd(b % a, a); } typedef long long lld; int dir[10][2] = { 
    { 
   -1,-1}, { 
   0,-1}, { 
   1,-1}, { 
   -1,0}, { 
   0,0}, { 
   1,0}, { 
   -1,1}, { 
   0,1}, { 
   1,1}, }; // 2A = 2s+p-2 char str[ + 10]; void solve() { 
    int T; scanf("%d", &T); while (T--) { 
    scanf("%s", str); pair<lld, lld> pre(0, 0), now; lld area = 0; for (int i = 0; str[i] != '5'; ++i) { 
    int d = str[i] - '1'; now.first = pre.first + dir[d][0]; now.second = pre.second+ dir[d][1]; area += pre.first * now.second - pre.second * now.first; pre = now; } if(area<0)area = -(area); printf("%lld",area/2); if (area & 1) { 
    printf(".5"); } puts(""); } } int main() { 
    solve(); return 0; } 

讯享网

皮克定理应用一

http://poj.org/problem?id=2954

题目大意

给定1个三角形,顶点都是整数,求内部整数点数量。

思路

通过顶点求出面积。
三条边的坐标,可以求出3条边经过整点的数量。
利用公式即可求出内部点。

代码

需要用c++提交
需要用c++提交
需要用c++提交

讯享网#include<stdio.h> #include<cmath> #include <algorithm> #include <vector> using namespace std; int gcd(int a, int b) { 
    if (a < 0 || b < 0)return gcd(abs(a), abs(b)); if (a > b)return gcd(b, a); if (a == 0)return b; return gcd(b % a, a); } // 2A = 2s+p-2 void solve() { 
    int x1, y1, x2, y2, x3, y3; while(scanf("%d%d%d%d%d%d", &x1, &y1, &x2, &y2, &x3, &y3) != EOF) { 
    if (x1 == 0 && x2 == 0 && x3 == 0 && y1 == 0 && y2 == 0 && y3 == 0)break; int edgePoints = 0; pair<int, int>p0(x2 - x1, y2 - y1); pair<int, int>p1(x3 - x2, y3 - y2); pair<int, int>p2(x1 - x3, y1 - y3); int area = abs(p0.first*p1.second - p0.second*p1.first); edgePoints += gcd(p0.first, p0.second); edgePoints += gcd(p1.first, p1.second); edgePoints += gcd(p2.first, p2.second); int innerPoint = (area - edgePoints) / 2 +1; printf("%d\n", innerPoint); } } int main() { 
    solve(); return 0; } 

皮克定理应用二

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

题目大意

给定机器人每次行走的向量,求最后合围区域的内部点,边界点,和面积。

思路

通过顶点求出面积。
每条边上的顶点可以单独求出。
利用公式即可求出内部点。

代码

需要用c++提交
需要用c++提交
需要用c++提交

#include<stdio.h> #include<cmath> #include <algorithm> #include <vector> using namespace std; int gcd(int a, int b) { 
    if (a < 0 || b<0)return gcd(abs(a), abs(b)); if (a > b)return gcd(b, a); if (a == 0)return b; return gcd(b % a, a); } // 2A = 2s+p-2 void solve() { 
    int T; scanf("%d", &T); int N; for (int k = 1; k <= T;++k) { 
    scanf("%d", &N); int edgePoints = 0; pair<int, int> p0(0,0); pair<int, int> pre=p0, now; int area = 0; for (int i = 0; i < N; ++i) { 
    scanf("%d %d", &now.first, &now.second); edgePoints += gcd(now.first, now.second); now.first += pre.first; now.second += pre.second; area += pre.first * now.second - pre.second * now.first; pre = now; } area = abs(area); int innerPoint = (area + 2 - edgePoints) / 2; printf("Scenario #%d:\n", k); printf("%d %d %.1f\n\n", innerPoint, edgePoints, area*1.0/2); } } int main() { 
    solve(); return 0; } /* 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 */ 

本人码农,希望通过自己的分享,让大家更容易学懂计算机知识。

在这里插入图片描述

小讯
上一篇 2025-03-12 13:04
下一篇 2025-01-14 14:26

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/32946.html