慕道子 发表于 2021-12-9 17:21:07

代码提交后显示错误9%,感觉没有错

https://s1.ax1x.com/2021/12/09/oht7XF.jpg
题目描述
给出一个简单凸多边形(没有缺口)(凸多边形:没有任何一个内角是优角(Reflexive Angle)的多边形)。求计算多边形的面积。
多边形被放置在一个X−Y的笛卡尔平面上,然后按逆时针方向给出各顶点的坐标值。所有的坐标值都是整数。

输入
第一行给出多边形的顶点数n(3<=n≤100)。接下来的几行每行给出多边形一个顶点的坐标值X和Y(都为整数并且用空格隔开)。
顶点按逆时针方向逐个给出。并且多边形的每一个顶点的坐标值−200≤x,y≤200。
多边形最后是靠从最后一个顶点到第一个顶点画一条边来封闭的。

输出
多边形的面积,输出保留两位小数。

样例输入 Copy
7
4 2
2 6
-2 8
-6 6
-8 4
-6 0
-2 -2
样例输出 Copy
74.00

#include <stdio.h>
int main()
{
        int n=0;
        int x,y,min=0,l=0;       
        double sum=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
                scanf("%d",&x);
                scanf("%d",&y);
                if(y>y)
                {
                        min=i;
                }
        }
        for(int i=0;i<n;i++)
        {
                y=y-y;
        }
        l=x-x;
        l=-l;
        sum=sum+(y+y)*l;
        for(int i=1;i<n;i++)
        {
                l=x-x;
                l=-l;
                sum=sum+(y+y)*l;
        }
        printf("%.2lf",sum/2);
        return 0;
}

慕道子 发表于 2021-12-11 17:08:20

嗯,哈哈,忘了把最小值取出来了,所以相减时会被覆盖,导致最小值后面的数减的是0。
解决方法是改成min=y;y-min;或者不提前减,直接在面积计算中使用用过程值.

wp231957 发表于 2021-12-11 08:10:42

你用的是哪个公式求面积

慕道子 发表于 2021-12-11 17:10:23

wp231957 发表于 2021-12-11 08:10
你用的是哪个公式求面积

没有用公式,用的自己想的土方法,属于中学几何的切割法吧

傻眼貓咪 发表于 2021-12-11 18:15:44

慕道子 发表于 2021-12-11 17:10
没有用公式,用的自己想的土方法,属于中学几何的切割法吧

其实我也默默关注这题,我也想知道方法,你说中学几何的切割法要切割 n <= 100 次?

傻眼貓咪 发表于 2021-12-11 18:53:47

找到公式了{:5_109:}
C 代码:#include <stdio.h>
#include <stdlib.h>

typedef struct{
    int x, y;
}point;

double area(int n, point arr[]){
    double res = 0;
    int x, y;
    for(int i = 0; i < n-1; i++){
      x = arr.x;
      y = arr.y;
      res += x*y;
    }
    x = arr.x;
    y = arr.y;
    res += x*y;
    for(int i = 0; i < n-1; i++){
      x = arr.x;
      y = arr.y;
      res -= x*y;
    }
    x = arr.x;
    y = arr.y;
    res -= x*y;
    return .5*abs(res);
}

int main()
{
    point points = {{4, 2}, {2, 6}, {-2, 8}, {-6, 6}, {-8, 4}, {-6, 0}, {-2, -2}};
    printf("%.2lf", area(7, points));
    return 0;
}输出结果:74.00

Python 代码:def area(n, arr):
      res = 0
      for i in range(n-1):
                x = arr
                y = arr
                res += x*y
      x = arr
      y = arr
      res += x*y
      for i in range(n-1):
                x = arr
                y = arr
                res -= x*y
      x = arr
      y = arr
      res -= x*y
      return .5*abs(res)
points = [(4, 2), (2, 6), (-2, 8), (-6, 6), (-8, 4), (-6, 0), (-2, -2)]
print(area(7, points))输出结果:74.00

慕道子 发表于 2021-12-11 18:59:16

傻眼貓咪 发表于 2021-12-11 18:15
其实我也默默关注这题,我也想知道方法,你说中学几何的切割法要切割 n

不用切割那么多次,不是那样切割的。
就是边数为n,然后每条边作垂线,构成n个梯形(三角形也是算梯形),然后上底加下底乘高除以2;累次相加,和为面积。
其中,y,y为底,h=x-x为高,而且h取负后正好上面的边构成的梯形的面积为正,下面边的为负,相加正好是上面的梯形面积和减去下面多余的梯形面积和,结果为图形面积。
正确代码
#include <stdio.h>
int main()
{
        int n=0;
        int x,y,min=0,l=0;       
        double sum=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
                scanf("%d",&x);
                scanf("%d",&y);
                if(y>y)
                {
                        min=i;
                }
        }
        min=y;
        for(int i=0;i<n;i++)
        {
                y=y-min;
        }
        l=x-x;
        l=-l;
        sum=sum+(y+y)*l;
        for(int i=1;i<n;i++)
        {
                l=x-x;
                l=-l;
                sum=sum+(y+y)*l;
        }
        printf("%.2lf",sum/2);
        return 0;
}


答案代码
#include <stdio.h>
#include <math.h>

typedef struct Node{// 定义一个结构体即表示点,又表示向量
    double x,y ;
}node;

node p ;// 因为最多100个

double across(node a,node b){// 返回两个向量的叉乘
    return a.x * b.y - a.y * b.x ;
}

double area(node a,node b,node c){// 将三个点转化为两条边的向量
    node x,y ;
    x.x = b.x - a.x ;
    x.y = b.y - a.y ;
    y.x = c.x - a.x ;
    y.y = c.y - a.y ;
    return across(x,y) ;
}

int main()
{
    int n ;
    scanf("%d",&n) ;
   
    for(int i = 0 ; i < n ; i++){
      scanf("%lf%lf",&p.x,&p.y) ;
    }

    double ans = 0 ;
    for(int i = 1 ; i + 1 < n ; i++){
      ans += area(p,p,p) ; // 划分的三角形第一个点固定为p,剩下的从两个点为i和i+1,这样来枚举所有三角形。
    }

    printf("%.2f\n",ans / 2) ;
    return 0;
}

慕道子 发表于 2021-12-11 19:11:09

傻眼貓咪 发表于 2021-12-11 18:53
找到公式了
C 代码:输出结果:



看来咱俩当时都在写{:5_109:}

傻眼貓咪 发表于 2021-12-11 19:11:12

慕道子 发表于 2021-12-11 18:59
不用切割那么多次,不是那样切割的。
就是边数为n,然后每条边作垂线,构成n个梯形(三角形也是算梯形), ...

原来是这样,受教了,谢谢你,这也是个好办法。

我是直接用数学公式计算的
页: [1]
查看完整版本: 代码提交后显示错误9%,感觉没有错