【OI好题推荐 #1】洛谷-P1183 多边形的面积

题目来源:洛谷

难度:普及+/提高(绿题)

链接:link

【重要】请读者在阅读下面的文章前至少先了解此题的含义

1 题目分析

这道题是一道有关计算几何的题。

我们先来解释几个题目有关的概念:

  • 笛卡尔平面:可以理解为平面直角坐标系
  • 靠从最后一个顶点到第一个顶点画一条边来封闭:图形边界无相交处

1.1 做法一:计算占格数量

这道题中的关键信息为:它的边要么是垂直的,要么是水平的。

既然这个多边形全部在格子上,是不是就意味着对于这个多边形来说,只要它占有了一个格子,就说明它占有了这个格子的全部呢?所以我们可以只需要统计它占格的数量即可。

如图,我分别用两种颜色标出了两种走向的边。我们不妨分别尝试一遍整张图从上至下,从左至右的扫描方式。对于绿边来说,当我们扫到第一条绿边时,开始出现阴影格子,扫到第二条时,暂时不再出现阴影格子,第三条时继续出现,第四条时再次停止,如此反复,直到最右下角的格子被扫描上为止。此时计算扫到了多少格子,就可以了。

计算一波时空复杂度:

  • 时间复杂度:需要扫描完从左上角至右下角的所有格子,也就是最差需要扫描全图,复杂度为O(1),但常数项较大,最大可达200²=40000,还是可以接受的。
  • 空间复杂度:一个存图的数组,开到205*205(其他几乎可以忽略不计),绝对不超出

    125.00MB的限制。

做法二:数学公式

S=n+\frac{s}{2}-1

其中 S 为面积,n 为内部格点数目,s 为多边形边界上的格点数。扫描方式和上面的类似,在此处不加以赘述。

有兴趣者可以研究:洛谷讨论帖

2 代码实现

#include<bits/stdc++.h>
using namespace std;

#define MAXN 105
#define MAXXY 405
bool is_wall[MAXXY][MAXXY]={false}; 
struct point{
	int x,y;
}polygon[MAXN];//存储该多边形
bool cnt=false;
int ans;

int main(){	
	int n;
	scanf("%d",&n);
	
	for(int i=0;i<MAXXY;i++){
		for(int j=0;j<MAXXY;j++){
			is_wall[i][j]=false;
		}
	}
	for(int i=0;i<n;i++){
		scanf("%d %d",&polygon[i].x,&polygon[i].y);
	}
	int change;
	for(int i=0;i<n;i++){//核心标墙代码
		if(polygon[i].y==polygon[(i+1)%n].y){
			if(polygon[(i+1)%n].x>polygon[i].x){
				change=1;
			}else{
				change=-1;
			}
			for(int j=polygon[i].x+(change-1)/2;j!=polygon[(i+1)%n].x+
                                              (change-1)/2;j+=change){
				is_wall[polygon[i].y+200][j+200]=true;
			}
		}
	}
	for(int i=-200;i<=200;i++){//核心累加代码
		for(int j=-200;j<=200;j++){
			if(is_wall[j+200][i+200]){
				cnt=!cnt;
			}
			if(cnt){
				ans++;
			}
		}
	}
	printf("%d\n",ans);//输出
	
	return 0;	
} 

参考资料

洛谷讨论帖icon-default.png?t=M3K6https://www.luogu.com.cn/discuss/396530洛谷题目-P1183 多边形的面积icon-default.png?t=M3K6https://www.luogu.com.cn/problem/P1183

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值