POJ 1265 Area (皮克公式+多边形面积)

http://poj.org/problem?id=1265
题意:一机器人从原点出发进行 n n n次移动,每次向右移动 d x i dx_i dxi,向上移动 d y i dy_i dyi,求其路线(不含原点)画成的多边形内部有多少格点,边界上有多少格点,及其面积多大。

Pick公式
对于顶点坐标均为整数的简单多边形:
面 积 = 内 部 格 点 数 目 + 边 界 格 点 数 目 / 2 − 1 面积=内部格点数目+边界格点数目/2-1 =+/21
边界格点数目
把每条边当做左开右闭区间以避免重复,一条左开右闭的线段(x1,y1)->(x2,y2)上格点数为:
g c d ( x 2 − x 1 , y 2 − y 1 ) gcd(x2-x1,y2-y1) gcd(x2x1,y2y1)
然后面积用叉积求得即可。
这里要注意的是POJ的鬼畜评测机,交G++的话面积需要%f才能过,%lf一直WA,交C++的话就随便过。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <cmath>
using namespace std;

struct Point
{
    double x,y;
    Point(){}
    Point(double _x,double _y)
	{
		x=_x;y=_y;
	}
	Point operator -(const Point &b)const
	{
		return Point(x-b.x,y-b.y);
	}
	Point operator +(const Point &b)const
	{
		return Point(x+b.x,y+b.y);
	}
    double operator ^(const Point &b)const
    {
        return x*b.y-y*b.x;
    }
};
Point p[110];
int T,n;
int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int main()
{
    scanf("%d",&T);
    for(int cas=1;cas<=T;cas++)
    {
        int ans1=0,ans2=0;
        double res=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        for(int i=1;i<n;i++)
            p[i]=p[i-1]+p[i];
        for(int i=0;i<n;i++)
            ans1+=gcd(abs((int)(p[(i+1)%n].x-p[i].x)),abs((int)(p[(i+1)%n].y-p[i].y)));
        for(int i=0;i<n;i++)
            res+=(p[i]^p[(i+1)%n])/2;
        res=fabs(res);
        ans2=int(res)+1-ans1/2;
        printf("Scenario #%d:\n%d %d %.1lf\n\n",cas,ans2,ans1,res);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值