Hoj 1157 SCUD Busters

来源:互联网 发布:亚米网络兼职 编辑:程序博客网 时间:2024/04/30 00:37

题目链接:http://acm.hit.edu.cn/hoj/problem/view?id=1157

题意:求凸包,求凸包面积,判断某一点在哪个凸包内。

水平序求凸包。

判断某一点在哪个凸包内可以使用叉积面积和是否等于多边形面积和,也可以用相邻的叉积方向是否一样来判读,本题练习第二种。

#include <iostream>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include <algorithm>using namespace std;#define Maxn 105#define Maxm 25int n;int cnt;struct Point{    int x;    int y;};Point p[Maxn];Point stack[Maxn];Point kingdom[Maxm][Maxn];bool k_used[Maxm];int k_top[Maxm];double k_size[Maxm];double det(Point a,Point b,Point o){    return (a.x - o.x)*(b.y - o.y) - (a.y - o.y) * (b.x - o.x);}bool cmp(Point a,Point b){    return a.y < b.y || (a.y == b.y && a.x < b.x);}//计算王国的面积double countSize(int k){    double ans = 0;    for(int i=1;i<k_top[k] - 1;i++)    {        ans += det(kingdom[k][i],kingdom[k][i+1],kingdom[k][0]);    }    ans /= 2;    return fabs(ans);}//判断点是否在给定的王国内bool isIn(int k,Point temp){    for(int i=0;i<k_top[k]-1;i++)    {        if(det(kingdom[k][i],kingdom[k][i+1],temp) * det(kingdom[k][i+1],kingdom[k][i+2],temp) <0)            return false;    }    return true;}//水平序求凸包void grahamScan(){    int top = -1;    stack[++top] = p[0];    stack[++top] = p[1];    for(int i=2;i<n;i++)    {        while(top && det(stack[top],p[i],stack[top-1])<0)        {            top--;        }        stack[++top] = p[i];    }    int midtop = top;    for(int i=n-2;i>=0;i--)    {        while(top>midtop && det(stack[top],p[i],stack[top-1])<0)        {            top--;        }        stack[++top] = p[i];    }    for(int i=0;i<=top;i++) kingdom[cnt][i] = stack[i];    k_top[cnt] = top;    k_size[cnt] = countSize(cnt);}double solve(int x,int y){    Point temp;    double ans = 0;    temp.x = x,temp.y = y;    for(int i=0;i<cnt;i++)    {        if(!k_used[i] && isIn(i,temp))        {            ans = k_size[i];            k_used[i] = true;            break;        }    }    return ans;}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);#endif    cnt = 0;    memset(k_used,false,sizeof(k_used));    while(scanf(" %d",&n)!=EOF && n!=-1)    {        for(int i=0;i<n;i++) scanf(" %d %d",&p[i].x,&p[i].y);        sort(p,p+n,cmp);        grahamScan();        cnt++;    }    int x,y;    double ans = 0;    while(scanf(" %d %d",&x,&y)!=EOF)    {        ans += solve(x,y);    }    printf("%.2lf\n",ans);    return 0;}


原创粉丝点击