poj 1654 Area

本文介绍了一种使用C语言计算由字符指令生成的多边形面积的方法,通过自定义坐标变化来更新顶点位置,并利用叉乘计算公式得出面积。为确保精度,采用整数运算并考虑了奇偶性对结果的影响。
#include<stdio.h>
#include<string.h>
#define Max 1000100
char s[Max];
struct Point
{
    int x,y;
} p[Max];
long long myfabs(long long x)
{
    if(x<0)x=-x;
    return x;
}
int xmult(Point p1,Point p2,Point p0)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
long long cal(Point *p,int n)
{
    int i,j;
    long long ans=0;
    for(i=1; i<n-1; i++)
    {
        ans+=xmult(p[i],p[i+1],p[0]);
    }
    return ans;
}
int x,y;
void change(char c)
{
    if(c=='1')
    {
        x-=1;
        y-=1;
    }
    else if(c=='2')y-=1;
    else if(c=='3')
    {
        x+=1;
        y-=1;
    }
    else if(c=='4')x-=1;
    else if(c=='6')x+=1;
    else if(c=='7')
    {
        x-=1;
        y+=1;
    }
    else if(c=='8')y+=1;
    else if(c=='9')
    {
        x+=1;
        y+=1;
    }
}
int main()
{
    int i,n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",s);
        x=y=0;
        p[0].x=p[0].y=0;
        int sl=strlen(s);
        for(i=1; i<sl; i++)
        {
            change(s[i-1]);
            p[i].x=x;p[i].y=y;
        }
        //memset(s,0,sizeof(s));
        long long ans=cal(p,sl);
       // printf("%d#",ans);
        if(ans&1)
            printf("%I64d.5\n",myfabs(ans/2));
        else
            printf("%I64d\n",myfabs(ans/2));
    }

    return 0;
}

用double精度不够

用int范围不够;

第二种解决方法(处理机器误差):

#include<stdio.h>
#include<string.h>
#include<math.h>
#define Max 1000100
#define eps 1e-12
char s[Max];
struct Point
{
    int x,y;
} p[Max];
long long myfabs(long long x)
{
    if(x<0)x=-x;
    return x;
}
int xmult(Point p1,Point p2,Point p0)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
}
long long cal(Point *p,int n)
{
    int i,j;
    long long ans=0;
    for(i=1; i<n-1; i++)
    {
        ans+=xmult(p[i],p[i+1],p[0]);
    }
    return ans;
}
int x,y;
void change(char c)
{
    if(c=='1')
    {
        x-=1;
        y-=1;
    }
    else if(c=='2')y-=1;
    else if(c=='3')
    {
        x+=1;
        y-=1;
    }
    else if(c=='4')x-=1;
    else if(c=='6')x+=1;
    else if(c=='7')
    {
        x-=1;
        y+=1;
    }
    else if(c=='8')y+=1;
    else if(c=='9')
    {
        x+=1;
        y+=1;
    }
}
int main()
{
    int i,n;
    scanf("%d",&n);
    while(n--)
    {
        scanf("%s",s);
        x=y=0;
        p[0].x=p[0].y=0;
        int sl=strlen(s);
        for(i=1; i<sl; i++)
        {
            change(s[i-1]);
            p[i].x=x;p[i].y=y;
        }
        //memset(s,0,sizeof(s));
        long long ans=cal(p,sl);
       // printf("%d#",ans);
        //if(ans&1)
        double anx=(double)ans/2;
        if(fabs(anx-(long long)anx)<eps)
            printf("%I64d\n",myfabs(anx));
        else
            printf("%.1lf\n",fabs((double)ans/2));
    }

    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/XDJjy/p/3236593.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值