a×b
a与b夹角小于180度(逆时针),那么这个值就是正值,大于180度就是负值
a与b夹角小于180度(逆时针),那么这个值就是正值,大于180度就是负值
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 10001;
typedef struct point
{
int x, y;
}point;
point p[maxn];
int s1[maxn];
int cnt;
int n;
int dist(point a, point b)
{
return (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y);
}
int cross(point p0, point p1, point p2)
{
return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
bool cmp(point a, point b)
{
int tmp = cross(p[0], a, b);
if(tmp != 0) return tmp > 0;
return dist(p[0], a) <= dist(p[0], b);
}
void graham();
int darea(point m, point n); //每个小三角形的两倍
int dsumarea();
int main()
{
int i;
int pos = 0;
while(~scanf("%d", &n))
{
for(i = 0; i < n; ++i) //保证p[0]的y,x最小
{
scanf("%d %d", &p[i].x, &p[i].y);
if(p[i].y < p[pos].y || (p[i].y == p[pos].y && p[i].x < p[pos].x))
pos = i;
}
swap(p[0], p[pos]);
graham();
int ans = dsumarea() / (50 * 2);
printf("%d\n", ans);
}
return 0;
}
int darea(point m, point n) //每个小三角形的两倍
{
return (m.x-p[0].x)*(n.y-p[0].y)-(m.y-p[0].y)*(n.x-p[0].x);
}
int dsumarea() //总面积的两倍
{
int i, j;
int sum = 0;
for(i = 1; i < cnt - 1; ++i)
{
sum += darea(p[s1[i]], p[s1[i + 1]]);
}
return sum;
}
void graham()
{
int i;
//找到(x, y)最小的点
cnt = 0;
sort(p + 1, p + n, cmp);
s1[cnt++] = 0;
s1[cnt++] = 1;
for(i = 2; i < n; ++i)
{
while(cross(p[s1[cnt - 2]], p[s1[cnt - 1]], p[i]) < 0) --cnt;
s1[cnt++] = i;
}
}