鱼C论坛

 找回密码
 立即注册
查看: 1694|回复: 8

[已解决]代码提交后显示错误9%,感觉没有错

[复制链接]
发表于 2021-12-9 17:21:07 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x

                               
登录/注册后可看大图

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

输入
第一行给出多边形的顶点数n(3<=n≤100)。接下来的几行每行给出多边形一个顶点的坐标值X和Y(都为整数并且用空格隔开)。
顶点按逆时针方向逐个给出。并且多边形的每一个顶点的坐标值&#8722;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[101],y[101],min=0,l=0;       
        double sum=0;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
                scanf("%d",&x[i]);
                scanf("%d",&y[i]);
                if(y[min]>y[i])
                {
                        min=i;
                }
        }
        for(int i=0;i<n;i++)
        {
                y[i]=y[i]-y[min];
        }
        l=x[0]-x[n-1];
        l=-l;
        sum=sum+(y[0]+y[n-1])*l;
        for(int i=1;i<n;i++)
        {
                l=x[i]-x[i-1];
                l=-l;
                sum=sum+(y[i]+y[i-1])*l;
        }
        printf("%.2lf",sum/2);
        return 0;
}
最佳答案
2021-12-11 19:11:12
慕道子 发表于 2021-12-11 18:59
不用切割那么多次,不是那样切割的。
就是边数为n,然后每条边作垂线,构成n个梯形(三角形也是算梯形), ...

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

我是直接用数学公式计算的
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2021-12-11 17:08:20 | 显示全部楼层
嗯,哈哈,忘了把最小值取出来了,所以相减时会被覆盖,导致最小值后面的数减的是0。
解决方法是改成min=y[min];y[i]-min;或者不提前减,直接在面积计算中使用用过程值.
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-11 08:10:42 From FishC Mobile | 显示全部楼层
你用的是哪个公式求面积
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-12-11 17:10:23 | 显示全部楼层
wp231957 发表于 2021-12-11 08:10
你用的是哪个公式求面积

没有用公式,用的自己想的土方法,属于中学几何的切割法吧
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-11 18:15:44 | 显示全部楼层
慕道子 发表于 2021-12-11 17:10
没有用公式,用的自己想的土方法,属于中学几何的切割法吧

其实我也默默关注这题,我也想知道方法,你说中学几何的切割法要切割 n <= 100 次?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-11 18:53:47 | 显示全部楼层
找到公式了
C 代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. typedef struct{
  4.     int x, y;
  5. }point;

  6. double area(int n, point arr[]){
  7.     double res = 0;
  8.     int x, y;
  9.     for(int i = 0; i < n-1; i++){
  10.         x = arr[i].x;
  11.         y = arr[i+1].y;
  12.         res += x*y;
  13.     }
  14.     x = arr[n-1].x;
  15.     y = arr[0].y;
  16.     res += x*y;
  17.     for(int i = 0; i < n-1; i++){
  18.         x = arr[i+1].x;
  19.         y = arr[i].y;
  20.         res -= x*y;
  21.     }
  22.     x = arr[0].x;
  23.     y = arr[n-1].y;
  24.     res -= x*y;
  25.     return .5*abs(res);
  26. }

  27. int main()
  28. {
  29.     point points[7] = {{4, 2}, {2, 6}, {-2, 8}, {-6, 6}, {-8, 4}, {-6, 0}, {-2, -2}};
  30.     printf("%.2lf", area(7, points));
  31.     return 0;
  32. }
复制代码
输出结果:
  1. 74.00
复制代码



Python 代码:
  1. def area(n, arr):
  2.         res = 0
  3.         for i in range(n-1):
  4.                 x = arr[i][0]
  5.                 y = arr[i+1][1]
  6.                 res += x*y
  7.         x = arr[n-1][0]
  8.         y = arr[0][1]
  9.         res += x*y
  10.         for i in range(n-1):
  11.                 x = arr[i+1][0]
  12.                 y = arr[i][1]
  13.                 res -= x*y
  14.         x = arr[0][0]
  15.         y = arr[n-1][1]
  16.         res -= x*y
  17.         return .5*abs(res)
  18. points = [(4, 2), (2, 6), (-2, 8), (-6, 6), (-8, 4), (-6, 0), (-2, -2)]
  19. print(area(7, points))
复制代码
输出结果:
  1. 74.00
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

不用切割那么多次,不是那样切割的。
就是边数为n,然后每条边作垂线,构成n个梯形(三角形也是算梯形),然后上底加下底乘高除以2;累次相加,和为面积。
其中,y[i],y[i-1]为底,h=x[i]-x[i-1]为高,而且h取负后正好上面的边构成的梯形的面积为正,下面边的为负,相加正好是上面的梯形面积和减去下面多余的梯形面积和,结果为图形面积。
正确代码
  1. #include <stdio.h>
  2. int main()
  3. {
  4.         int n=0;
  5.         int x[101],y[101],min=0,l=0;       
  6.         double sum=0;
  7.         scanf("%d",&n);
  8.         for(int i=0;i<n;i++)
  9.         {
  10.                 scanf("%d",&x[i]);
  11.                 scanf("%d",&y[i]);
  12.                 if(y[min]>y[i])
  13.                 {
  14.                         min=i;
  15.                 }
  16.         }
  17.         min=y[min];
  18.         for(int i=0;i<n;i++)
  19.         {
  20.                 y[i]=y[i]-min;
  21.         }
  22.         l=x[0]-x[n-1];
  23.         l=-l;
  24.         sum=sum+(y[0]+y[n-1])*l;
  25.         for(int i=1;i<n;i++)
  26.         {
  27.                 l=x[i]-x[i-1];
  28.                 l=-l;
  29.                 sum=sum+(y[i]+y[i-1])*l;
  30.         }
  31.         printf("%.2lf",sum/2);
  32.         return 0;
  33. }
复制代码



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

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

  6. node p[110] ;  // 因为最多100个

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

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

  18. int main()
  19. {
  20.     int n ;
  21.     scanf("%d",&n) ;
  22.      
  23.     for(int i = 0 ; i < n ; i++){
  24.         scanf("%lf%lf",&p[i].x,&p[i].y) ;
  25.     }

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

  30.     printf("%.2f\n",ans / 2) ;
  31.     return 0;
  32. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2021-12-11 19:11:09 | 显示全部楼层
傻眼貓咪 发表于 2021-12-11 18:53
找到公式了
C 代码:输出结果:


看来咱俩当时都在写
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-11 19:11:12 | 显示全部楼层    本楼为最佳答案   
慕道子 发表于 2021-12-11 18:59
不用切割那么多次,不是那样切割的。
就是边数为n,然后每条边作垂线,构成n个梯形(三角形也是算梯形), ...

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

我是直接用数学公式计算的
Area of Polygon.jpg
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-7-4 18:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表