hdu 4946 Area of Mushroom(凸包)

题意:平面上有n个人,每个人有一个速度v,平面上的一个位置被某个人控制,当且仅当这个人到达这个位置是最快的,问每个人控制的区域是不是无穷大的。

思路:速度小的肯定不可能控制无穷大的区域。那么就剩下速度值最大且相等的那一部分人了,可以发现,在这些人形成的凸包内部的点是不会控制无穷大的区域的,剩下的就是凸包上的点,这些点如果有两个点在同一个位置,那么它们都不行。另外注意一下速度最大值为0的情况就行了。


代码:


#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<cmath>
#include<vector>
#define inf 0x3f3f3f3f
#define Inf 0x3FFFFFFFFFFFFFFFLL
#define eps 1e-8
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
const int maxn =500 + 10;
struct Point
{
    int x, y;
    Point(int x=0, int y=0):x(x),y(y){}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B){return Vector(A.x+B.x, A.y+B.y);}
Vector operator - (Vector A, Vector B){return Vector(A.x-B.x, A.y-B.y);}
Vector operator * (Vector A, int p){return Vector(A.x*p, A.y*p);}
Vector operator / (Vector A, int p){return Vector(A.x/p, A.y/p);}
bool operator < (Point a, Point b)
{
    return a.x<b.x ||(a.x == b.x && a.y < b.y);
}
int dcmp(double x)
{
    if(fabs(x)<eps) return 0; else return x < 0 ? -1 : 1;
}
bool operator == (Point a, Point b)
{
    return a.x == b.x && a.y == b.y;
}
int Cross(Vector A, Vector B) {return A.x*B.y - A.y*B.x;}
int ConvexHull(Point* p, int n, Point* ch)
{
    sort(p, p+n);
    n = unique(p, p+n) - p; //去重
    int m = 0;
    for(int i = 0 ; i < n ; ++ i)
    {
        while(m > 1 && Cross(ch[m-1]-ch[m-2], p[i] - ch[m-2]) < 0) m--;
        ch[m++] = p[i];
    }
    int k = m;
    for(int i = n-2 ; i >= 0 ; -- i)
    {
        while(m > k && Cross(ch[m-1]-ch[m-2], p[i] - ch[m-2]) < 0) m--;
        ch[m++] = p[i];
    }
    if(n > 1) m--;
    return m;
}
Point pt[maxn<<1],p[maxn<<1];
int ans[maxn],S[maxn];
pair<int,Point>pnode[maxn];
int main()
{
//    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    int n,tcase = 0;
    while(~scanf("%d",&n))
    {
        if(n == 0) break;
        int x, y ,v ,vmax = 0;
        for(int i = 0; i < n;++i)
        {
            scanf("%d%d%d",&x,&y,&v);
            pnode[i] = make_pair(v,Point(x,y));
            vmax = max(v,vmax);
        }
        printf("Case #%d: ",++tcase);
        memset(ans,0,sizeof(ans));
        if(vmax)
        {
            int m = 0;
            for(int i = 0;i < n;++i)
                if(pnode[i].first == vmax)
                    p[m++] = pnode[i].second;
            m = ConvexHull(p,m,pt);
            for(int i = 0;i < m;++i)
            {
                int cnt = 0;
                for(int j = 0; j < n;++j)
                {
                    if(pnode[j].first == vmax && pt[i] == pnode[j].second)
                        S[cnt++] = j;
                }
                if(cnt == 1) ans[S[0]] = 1;
                else
                {
                    for(int k = 0;k < cnt;++k)
                        ans[S[k]] = 0;
                }
            }
        }
        for(int i = 0;i < n;++i)
            printf("%d",ans[i]);
        printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值