POJ1654 Area【多边形的面积】

                                 POJ1654 Area

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

题意

在一个网格中,你当前在起始点,然后给你一些数字,每个数字表示你往当前位置的8个方向走一个单位或根号2个单位(斜线方向)。然后你到了下一个网格点了,就这样让你走出一个多边形,要你输出该多边形的面积. 题目保证最后一步是回到原点,且保证能形成多边形。1,2,3,4,6,7,8,9分别表示西南、南、东南、西、东、西北、北、东北

输入

整数t (1 <= t <= 20)表示样例组数,每组一行数字序列,长度不超过1000000,以5结尾,数字序列表示从起始点出发的行进方向。

输出

形成的多边形的面积。

样例输入

4
5
825
6725
6244865

样例输出

0
0
0.5
2

分析

问题与起始点没有关系,因此可以将起始点设为原点,然后使用叉积求多边形的面积,需要注意的是,如果我们使用double类型表示面积,就不好按题目格式输出,考虑到各个点都是整数,且容易知道多边形的面积是0.5的倍数,因此我们可以使用long long类型表示面积,使用叉积算面积时先不除2,最后统一除2,通过查看是否为奇数,来决定是否在其后加0.5。具体看程序

C++程序

#include<iostream>
#include<cstring> 
#include<cmath>


using namespace std;

const int N=1000005;
typedef long long ll;

char s[N];

//方向 
int d[][2]={{0,0},{-1,-1},{0,-1},{1,-1},{-1,0},{0,0},{1,0},{-1,1},{0,1},{1,1}};

struct Point{
	ll x,y;
	Point(){}
	Point(ll x,ll y):x(x),y(y){}
	Point operator -(const Point &a)const
	{
		return Point(x-a.x,y-a.y);
	}
	ll operator ^(const Point &a)const
	{
		return x*a.y-y*a.x;
	}
};

int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		scanf("%s",s);
		int len=strlen(s)-1;
		ll ans=0;
		Point p0(0,0),p1(0,0),p2(0,0);
		for(int i=0;i<len;i++)
		{
			//下一个点 
			p2.x=p1.x+d[s[i]-'0'][0];
			p2.y=p1.y+d[s[i]-'0'][1];
			ans+=((p1-p0)^(p2-p0));
			p1=p2;
		}
		if(ans<0) ans=-ans;
		printf("%lld%s\n",ans/2,ans%2==1?".5":"");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/SongBai1997/article/details/85017595
今日推荐