鱼C论坛

 找回密码
 立即注册
查看: 1414|回复: 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个梯形(三角形也是算梯形), ...

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

我是直接用数学公式计算的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

使用道具 举报

发表于 2021-12-11 08:10:42 From FishC Mobile | 显示全部楼层
你用的是哪个公式求面积
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

没有用公式,用的自己想的土方法,属于中学几何的切割法吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

其实我也默默关注这题,我也想知道方法,你说中学几何的切割法要切割 n <= 100 次?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-12-11 18:53:47 | 显示全部楼层
找到公式了
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[i].x;
        y = arr[i+1].y;
        res += x*y;
    }
    x = arr[n-1].x;
    y = arr[0].y;
    res += x*y;
    for(int i = 0; i < n-1; i++){
        x = arr[i+1].x;
        y = arr[i].y;
        res -= x*y;
    }
    x = arr[0].x;
    y = arr[n-1].y;
    res -= x*y;
    return .5*abs(res);
}

int main()
{
    point points[7] = {{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[i][0]
                y = arr[i+1][1]
                res += x*y
        x = arr[n-1][0]
        y = arr[0][1]
        res += x*y
        for i in range(n-1):
                x = arr[i+1][0]
                y = arr[i][1]
                res -= x*y
        x = arr[0][0]
        y = arr[n-1][1]
        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
想知道小甲鱼最近在做啥?请访问 -> 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取负后正好上面的边构成的梯形的面积为正,下面边的为负,相加正好是上面的梯形面积和减去下面多余的梯形面积和,结果为图形面积。
正确代码
#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;
                }
        }
        min=y[min];
        for(int i=0;i<n;i++)
        {
                y[i]=y[i]-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;
}


答案代码
#include <stdio.h>
#include <math.h>
 
typedef struct Node{  // 定义一个结构体即表示点,又表示向量
    double x,y ;
}node;
 
node p[110] ;  // 因为最多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[i].x,&p[i].y) ;
    }
 
    double ans = 0 ;
    for(int i = 1 ; i + 1 < n ; i++){
        ans += area(p[0],p[i],p[i+1]) ; // 划分的三角形第一个点固定为p[0],剩下的从两个点为i和i+1,这样来枚举所有三角形。
    }
 
    printf("%.2f\n",ans / 2) ;
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

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


看来咱俩当时都在写
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

我是直接用数学公式计算的
Area of Polygon.jpg
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-23 07:18

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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