思路:肯定有规律啊(因为不会凸包
),这个多边形的相邻两条边的斜率是越来越小的,
后一条边总是小于前一条边的斜率,有的人用叉乘来解释的,原理貌似是一样的,都是边的方向。
PS:拓展一下,开始想的按照相对的点连起来的直线斜率也是符合这种规律的
![委屈](http://static.blog.csdn.net/xheditor/xheditor_emot/default/wronged.gif)
后一条边总是小于前一条边的斜率,有的人用叉乘来解释的,原理貌似是一样的,都是边的方向。
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;
}