题目概述
给定一个多边形中N个点的坐标x,y,每50面积可以放一个物体,求最多可放多少个物体
时限
2000ms/6000ms
输入
第一行正整数N,其后N行,每行两个整数x,y,输入到EOF为止
限制
1<=N<=10000;-1000<=x,y<=1000
输出
每行一个数,所求最多可放物体数
样例输入
4
0 0
0 101
75 0
75 101
样例输出
151
讨论
计算几何,求凸包面积,勉强算考了两个知识点,求凸包继续沿用之前的andrew算法,正好也省去点过少的两个特殊情况的处理,求面积,将多边形分割为多个小三角形,所有小三角形的一个顶点都是凸包的第一个点,其他的点都是凸包上相邻的点,其有向面积为共起点两向量的向量积的一半,最后加起来,除以50即可
实际上由于除以50的存在以及看上去好弱的数据,直接开int算面积和也不会出现偏差,不过还是避免这么做比较好
题解状态
208K,0MS,C++,1311B
题解代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define INF 0x3f3f3f3f
#define MAXN 10003
#define memset0(a) memset(a,0,sizeof(a))
#define EPS 1e-6
struct Pt//point 点的结构
{
int x, y;
bool operator<(Pt &b)const//直接重载小于 懒得单独写pred函数了
{
return y != b.y ? y < b.y : x < b.x;
}
}pts[MAXN];
int N;//点总数
int stk[MAXN], top;//stack 数组模拟栈及其栈顶
int xp(int x1, int y1, int x2, int y2, int x3, int y3)
{
return (x1 - x2)*(y3 - y2) - (y1 - y2)*(x3 - x2);
}
int fun()
{
for (int p = 0; p < N; p++)
scanf("%d%d", &pts[p].x, &pts[p].y);//input
sort(pts, pts + N);//排序 下面是andrew算法
for (int p = 0; p < N; p++) {
while (top > 1 && xp(pts[p].x, pts[p].y, pts[stk[top - 2]].x, pts[stk[top - 2]].y, pts[stk[top - 1]].x, pts[stk[top - 1]].y) >= 0)
top--;
stk[top++] = p;
}
int stklen = top;
for (int p = N - 2; p >= 0; p--) {
while (top > stklen&&xp(pts[p].x, pts[p].y, pts[stk[top - 2]].x, pts[stk[top - 2]].y, pts[stk[top - 1]].x, pts[stk[top - 1]].y) >= 0)
top--;
stk[top++] = p;
}
double sum = 0;//初始化面积 用int也行
for (int p = 1; p < top - 2; p++) {
sum += xp(pts[stk[p]].x, pts[stk[p]].y, pts[0].x, pts[0].y, pts[stk[p + 1]].x, pts[stk[p + 1]].y) / 2.0;//算出有向面积 为了避免是负的而调整了出现的顺序
}
return sum / 50;
}
int main(void)
{
//freopen("vs_cin.txt", "r", stdin);
//freopen("vs_cout.txt", "w", stdout);
while (~scanf("%d", &N) && N) {//input
printf("%d\n", fun());//output
top = 0;
}
}
EOF