题目链接:http://poj.org/problem?id=1654
You are going to compute the area of a special kind of polygon. One vertex of the polygon is the origin of the orthogonal coordinate system. From this vertex, you may go step by step to the following vertexes of the polygon until back to the initial vertex. For each step you may go North, West, South or East with step length of 1 unit, or go Northwest, Northeast, Southwest or Southeast with step length of square root of 2.

For example, this is a legal polygon to be computed and its area is 2.5:
Input
The first line of input is an integer t (1 <= t <= 20), the number of the test polygons. Each of the following lines contains a string composed of digits 1-9 describing how the polygon is formed by walking from the origin. Here 8, 2, 6 and 4 represent North, South, East and West, while 9, 7, 3 and 1 denote Northeast, Northwest, Southeast and Southwest respectively. Number 5 only appears at the end of the sequence indicating the stop of walking. You may assume that the input polygon is valid which means that the endpoint is always the start point and the sides of the polygon are not cross to each other.Each line may contain up to 1000000 digits.
Output
For each polygon, print its area on a single line.
Sample Input
4 5 825 6725 6244865
Sample Output
0 0 0.5 2
题目翻译:
您将计算特殊面的面积。多边形的一个顶点是正交坐标系的原点。在此顶点中,您可以一步一步地转到多边形的以下顶点,直到回到初始顶点。对于每一步,您可以走北、西、南或东,步长为 1 个单位,也可以以 2 平方根的步长走西北、东北、西南或东南。
例如,这是要计算的合法多边形,其面积为 2.5:
输入
第一行输入是一个整数 t (1 <= t <= 20),测试多边形的编号。以下每行都包含一个由数字 1-9 组成的字符串,描述多边形是如何从原点行走形成的。这里8、2、6和4代表北、南、东和西,9、7、3和1分别表示东北、西北、东南和西南。数字 5 只出现在序列的末尾,指示行走停止。可以假定输入多边形有效,这意味着端点始终是起始点,并且多边形的两侧不相互交叉。每行最多可包含 10000000 位数字。
输出
对于每个面,在一条线上打印其区域。
题意理解:给你一个字符串,初始坐标(0,0),字符串的数字分别对应向各个方位走,5代表结束,模拟一下就行了。
经典的求凸多边形有向面积的做法,不过这个题有些坑。
注意事项(来自discuss):
首先GCC会ce,G++会wa,不要用这两个编译器。
最终答案是要取绝对值,但fabs用c++居然会ce,
所以要手写abs 因为答案一定是整数或整数除以二,所以用整形存,不能用float或double。
还有答案可能爆int,所以要开longlong。
最坑的是不能所有的变量都开,会MLE,所以只开跟答案相关的就行。
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=1e6+5;
char s[maxn];
struct Point{
int x,y;
Point(int x=0,int y=0):x(x),y(y){}
}p[maxn];
typedef Point Vector;
Vector operator-(Point a,Point b){
return Vector(a.x-b.x,a.y-b.y);
}
int Cross(Point a,Point b){
return a.x*b.y-a.y*b.x;
}
long long my_abs(long long x){
return x<0?-x:x;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
scanf("%s",s);
int x=0,y=0;
int len=strlen(s);
int n=0;
p[n].x=0,p[n++].y=0;
for(int i=0;i<len;i++){
if(s[i]=='1'){
x-=1;
y-=1;
p[n].x=x;
p[n++].y=y;
}
else if(s[i]=='2'){
y-=1;
p[n].x=x;
p[n++].y=y;
}
else if(s[i]=='3'){
x+=1;
y-=1;
p[n].x=x;
p[n++].y=y;
}
else if(s[i]=='4'){
x-=1;
p[n].x=x;
p[n++].y=y;
}
else if(s[i]=='6'){
x+=1;
p[n].x=x;
p[n++].y=y;
}
else if(s[i]=='7'){
x-=1;
y+=1;
p[n].x=x;
p[n++].y=y;
}
else if(s[i]=='8'){
y+=1;
p[n].x=x;
p[n++].y=y;
}
else if(s[i]=='9'){
x+=1;
y+=1;
p[n].x=x;
p[n++].y=y;
}
if(s[i]=='5') break;
}
long long sum=0;
for(int i=1;i<n-1;i++)
sum+=Cross(p[i]-p[0],p[i+1]-p[0]);
sum=my_abs(sum);
if(sum%2) printf("%.1f\n",sum*1.0/2);
else printf("%lld\n",sum/2);
}
return 0;
}
本文介绍了一种计算特殊多边形面积的方法,通过解析由数字1-9组成的字符串来模拟从原点出发的路径,其中不同的数字代表不同的方向移动。文章提供了详细的代码实现,包括如何处理各种移动方向,计算有向面积并处理边界情况。

732

被折叠的 条评论
为什么被折叠?



