今日、学校の兄は、(グラハム・スキャン方式)と呼ばれているようだ...それについて少し書くように頼ま?
(これだけ)あまりにも料理
実際には、凸包を求めていることは非常に簡単です(?自分の野菜を叫びであることが、なぜが学ばなかった)
。最初の左下隅を見つけなければならない(それは凸包上の点でなければならない)
、ソート極角の中心として、その時点で
、その後、順番を排水しますスタック上の最初の2点
のベクトルの外積は、要素が脱積層し、負であれば、スタック構成最後から二番目の点と最後の点と決意の現在位置を決定負かスタックを退避しています木が少ない2よりも
スタックを置くポイント決意であります
以上のトラバースのすべてのポイントまでは、スタック要素は凸包上の点です...
コードは以下の通りである:(本当に何も価値がもっと言って...)
#include <iostream>
#include <algorithm>
#define MAX 1000
using namespace std;
struct node {
int x, y;
node(int _x = 0, int _y = 0)
{
x = _x;
y = _y;
}
node operator -(node a)//向量减
{
return node(x - a.x, y - a.y);
}
int operator*(node a)//叉乘
{
return (x * a.y - y * a.x);
}
friend int getdis(node a, node b)//两点间距离的平方
{
return ((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
void show()
{
cout << "x:" << x << " y:" << y << endl;
}
}p[MAX];
int ans[MAX];
int n;
int cmp(node a, node b)//极角排序
{
int t = (a - p[0]) * (b - p[0]);
if (t != 0)
return t > 0;
else
return getdis(a, p[0]) < getdis(b, p[0]);
}
void getans()
{
int len = 0;
ans[len++] = 0;
for (int i = 1; i < n; i++)
{
while (len >= 2 && ((p[ans[len - 1]] - p[ans[len - 2]]) * (p[i] - p[ans[len - 2]]) <= 0)) len--;
ans[len++] = i;
}//求凸包...
for (int i = 0; i < len; i++)
p[ans[i]].show();
int s = 0;
for (int i = 1; i+1 < len; i++)
{
s += (p[ans[i]] - p[0]) * (p[ans[i + 1]] - p[0]);
}//求凸多边形面积(因为我这里都是整数,就没用double...正常写肯定要用double的...)
cout << 1.0 * s / 2;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> p[i].x >> p[i].y;
int m = 0;//最左下的点的下标
for (int i = 1; i < n; i++)
{
if (p[i].y < p[m].y)
m = i;
else if (p[i].y == p[m].y && p[i].x < p[m].x)
m = i;
}
node t = p[m];
p[m] = p[0];
p[0] = t;//一定要把最左下的点和最开始的点换位置!!这里处理不好还会出莫名其妙的BUG(不知道为什么,对sort研究不深...)
sort(p, p + n, cmp);
getans();
return 0;
}
/*
9
1 0
3 2
2 0
2 1
2 2
2 3
1 1
0 0
3 3
*/