HDU 2108 Shape of HDU(凸包)

思路:肯定有规律啊(因为不会凸包委屈),这个多边形的相邻两条边的斜率是越来越小的,
后一条边总是小于前一条边的斜率,有的人用叉乘来解释的,原理貌似是一样的,都是边的方向。
PS:拓展一下,开始想的按照相对的点连起来的直线斜率也是符合这种规律的

此时判断相对的点,就是对称的两点

/*
这貌似没用到凸包的经典算法啊啊啊
*/
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;

double a[1005],b[1005],len[1005];
int main()
{
    int n;

    while(~scanf("%d",&n)&&n)
    {
        for(int i=1;i<=n;i++)
            scanf("%lf%lf",&a[i],&b[i]);
        a[n+1]=a[1],b[n+1]=b[1];
        a[n+2]=a[2],b[n+2]=b[2];
        //for(int i=1;i<=n;i++)
            //len[i]=sqrt((a[i+1]-a[i])*(a[i+1]-a[i])+(b[i+1]-b[i])*(b[i+1]-b[i]));
        bool flag=false;
        /*for(int i=1;i<=n;i++)
            for(int j=i+1;j<=n;j++)
                for(int k=j+1;k<=n;k++)
                    if(len[i]+len[j]<len[k]||len[i]+len[k]<len[j]||len[j]+len[k]<len[i])
                    {
                        flag=true;
                        break;
                    }
        */
        for(int i=1;i<=n;i++)
        {
            if((a[i+2]-a[i+1])*(b[i+1]-b[i])-(a[i+1]-a[i])*(b[i+2]-b[i+1])>0)
            {
                flag=true;
                break;
            }
        }
                if(flag)
                    cout<<"concave"<<endl;
                else
                    cout<<"convex"<<endl;
    }
    return 0;
}

用叉积来判断反而复杂了点,贴个简单点的叉积代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
const int N = 1005;
const int zero = 1e-6;
struct point
{
    double x,y;
    point(double xx=0,double yy=0):x(xx),y(yy){}
};
point p[N];
//直接硬性判断叉积,如果再求向量的话就复杂了很多
bool Cross(point a,point b,point c)
{
    if((b.y-a.y)*(c.x-a.x)-(b.x-a.x)*(c.y-a.y)>=zero)
        return true;
    return false;
}
int main()
{
    int n;
    while(~scanf("%d",&n) && n)
    {
        for(int i = 0;i < n;i++)
            scanf("%lf%lf",&p[i].x,&p[i].y);
        point a = p[0];
        point b = p[1];
        int flag  = 0;
        for(int i = 2;i < n;i++)
        {
            if(Cross(a,b,p[i]))
            {
                flag = 1;
                break;
            }
            a = b;
            b = p[i];
        }
        if(Cross(a,b,p[0]) || Cross(b,p[0],p[1]))
            flag = 1;
        if(flag)
            printf("concave\n");
        else
            printf("convex\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值