HDU 4946 Area of Mushroom(凸包)

如果一个人能统治无穷远处,那么他的速度一定是最大的。除了那几种很坑的数据,比如同一个点速度相同的两个人。永远都是不可能。所以你要处理出来所有速度最大的点,然后用他们构成一个凸包,你把端点的点求出来了,还得判断一下在边上的情况。然后顶点和在边上的点所构成的就是可以到达无穷远处的人。

PS:抄了芳姐的模版。。哈哈哈

Area of Mushroom

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 676    Accepted Submission(s): 120

Problem Description

Teacher Mai has a kingdom with the infinite area.

He has n students guarding the kingdom.

The i-th student stands at the position (xi,yi), and his walking speed is vi.

If a point can be reached by a student, and the time this student walking to this point is strictly less than other students, this point is in the charge of this student.

For every student, Teacher Mai wants to know if the area in the charge of him is infinite.

Input

There are multiple test cases, terminated by a line "0".

For each test case, the first line contains one integer n(1<=n<=500).

In following n lines, each line contains three integers xi,yi,vi(0<=|xi|,|yi|,vi<=10^4).

Output

For each case, output "Case #k: s", where k is the case number counting from 1, and s is a string consisting of n character. If the area in the charge of the i-th student isn‘t infinite, the i-th character is "0", else it‘s "1".

Sample Input

3
0 0 3
1 1 2
2 2 1
0

Sample Output

Case #1: 100

Source

2014 Multi-University Training Contest
8

#include <algorithm>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <iomanip>
#include <stdio.h>
#include <string>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <map>
#include <set>
#define eps 1e-9
///#define M 1000100
#define LL __int64
///#define LL long long
///#define INF 0x7ffffff
#define INF 0x3f3f3f3f
#define PI 3.1415926535898
#define zero(x) ((fabs(x)<eps)?0:x)
#define clearall(A, X) memset(A, X, sizeof(A))

using namespace std;

const int maxn = 2010;

struct point
{
    int x,y;
    int v,id;
    point(int x = 0,int y = 0):x(x),y(y) {}
} p[maxn],ch[maxn],q[maxn],pq[maxn];
int f[maxn];
typedef point pointt;
point operator -(point a,point b)
{
    return point(a.x-b.x,a.y-b.y);
}
int dcmp(double x)
{
    if(fabs(x)<eps) return 0;
    return x<0?-1:1;
}
int cross(point a,point b)
{
    return a.x*b.y-a.y*b.x;
}
int mul(point a,point b,point c)
{
    return cross(b-a,c-a);
}
double dis(point a)
{
    return sqrt(a.x*a.x+a.y*a.y);
}
bool cmp(point a,point b)
{
    if(mul(p[0],a,b)==0)
        return dis(a-p[0])<dis(b-p[0]);
    return mul(p[0],a,b)>0;
}
int graham(int n)///返回点的个数
{
    int i,k =0 ,top;
    if(n<2) return 0;
    point tmp ;
    for(i = 0; i < n ; i++)
    {
        if(dcmp(p[i].y-p[k].y)<0||(dcmp(p[i].y-p[k].y)==0&&dcmp(p[i].x-p[k].x)<0))
            k = i;
    }
    swap(p[k],p[0]);
    sort(p+1,p+n,cmp);
    ch[0] = p[0];
    ch[1] = p[1];
    top = 1;
    for(i = 2; i < n ; i++)
    {
        while(top>0&&dcmp(mul(ch[top-1],ch[top],p[i]))<=0) top--;
        top++;
        ch[top] = p[i];
    }
    return top;
}
bool cmpp(point a,point b)
{
    if(a.x==b.x) return a.y<b.y;
    return a.x<b.x;
}

int main()
{
    int Case = 1;
    int n;
    while(cin >>n)
    {
        if(!n) break;
        memset(f, 0, sizeof(f));
        int Max = -INF;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d %d %d",&q[i].x, &q[i].y, &q[i].v);
            q[i].id = i;
            if(!q[i].v) f[i] = -2;
            Max = max(Max, q[i].v);
        }
        for(int i = 1; i <= n; i++)
        {
            if(q[i].v != Max) continue;
            for(int j = i+1; j <= n; j++)
            {
                if(q[j].x == q[i].x && q[j].y == q[i].y && q[j].v == q[i].v)
                {
                    f[q[j].id] = -1;
                    f[q[i].id] = -1;
                }
            }
        }
        int t = 0;
        for(int i = 1; i <= n; i++)
            if(q[i].v == Max && f[q[i].id] != -2) p[t++] = q[i];
        int m = graham(t);
        cout<<"Case #"<<Case++<<": ";
        if(m < 2)
        {
            for(int i = 1; i <= n; i++)
            {
                if(f[i] != -1 && f[i] != -2 && q[i].v == Max) cout<<1;
                else cout<<0;
            }
            cout<<endl;
            continue;
        }
        ch[m+1] = ch[0];
        for(int i = 0; i <= m; i++) if(!f[ch[i].id]) f[ch[i].id] = 1;
        for(int i = 1; i <= n; i++)
        {
            if(f[i] || q[i].v != Max) continue;
            for(int j = 0; j <= m; j++)
                if(mul(ch[j], ch[j+1], q[i]) == 0) f[i] = 1;
        }
        for(int i = 1; i <= n; i++)
        {
            if(f[i] == 1) cout<<1;
            else cout<<0;
        }
        cout<<endl;
    }
    return 0;
}

HDU 4946 Area of Mushroom(凸包),布布扣,bubuko.com

时间: 2024-12-28 21:44:53

HDU 4946 Area of Mushroom(凸包)的相关文章

HDU 4946 Area of Mushroom 凸包 第八次多校

Problem Description Teacher Mai has a kingdom with the infinite area. He has n students guarding the kingdom. The i-th student stands at the position (xi,yi), and his walking speed is vi. If a point can be reached by a student, and the time this stud

HDU 4946 Area of Mushroom 共线凸包

题意是在二维平面上 给定n个人 每个人的坐标和移动速度v 若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点) 则这个点称作被x占有 若有人能占有无穷大的面积 则输出1 ,否则输出0 思路: 1.把所有点按速度排个序,然后把不是最大速度的点去掉 剩下的点才有可能是占有无穷大的面积 2.给速度最大的点做个凸包,则只有在凸包上的点才有可能占有无穷大 若一个位置有多个人,则这几个人都是不能占有无穷大的. 凸包上边里共线的点是要保留的,, 附赠一波数据 #include <cs

【凸包】HDU 4946 Area of Mushroom

注意: 1.重合的点 2.速度为0的点 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <ctype.h> #include <math.h> #include <string> #include <iostream> #include <algorithm> using

HDU 4946 Area of Mushroom 求凸包边上的点

点击打开链接 Area of Mushroom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1257    Accepted Submission(s): 307 Problem Description Teacher Mai has a kingdom with the infinite area. He has n studen

HDU 4946 Area of Mushroom(凸包)

HDU 4946 Area of Mushroom(凸包) ACM 题目地址:HDU 4946 Area of Mushroom 题意: 给定n个人,每个人的坐标和移动速度v,若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点),则这个点称作被x占有,若有人能占有无穷大的面积 则输出1 ,否则输出0. 分析: 到最后只有速度最大的点才有可能获得无穷大的面积.所以只要考虑速度最大的点. 很明显,只有这些点的凸包边上的点才能获得无穷大的面积. 所以求凸包边上的点就行了. 有

hdu 4946 Area of Mushroom

题意: 在二维平面上,给定n个人 每个人的坐标和移动速度v 若对于某个点,只有 x 能最先到达(即没有人能比x先到这个点或者同时到这个点) 则这个点称作被x占有,若有人能占有无穷大的面积 则输出1 ,否则输出0 思路: 1.把所有点按速度排个序,然后把不是最大速度的点去掉 剩下的点才有可能是占有无穷大的面积 2.给速度最大的点做个凸包,则只有在凸包上的点才有可能占有无穷大 若一个位置有多个人,则这几个人都是不能占有无穷大的. 凸包上边里共线的点是要保留的. #易错点: 1.凸包边上要保留共线的点

HDU 4946 Area of Mushroom(构造凸包)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4946 题目大意:在一个平面上有n个点p1,p2,p3,p4....pn,每个点可以以v的速度在平面上移动,对于平面上任意一点,假设有唯一一个点pi从初始的位置到这个点的时间最短,那么就说平面上的这个点是属于pi这点管辖的.现在要你判断pi管辖的范围是不是无穷大的,如果是输出1,否则输出0: 首先大致的方法就是构造凸包,不过要遵循一下前提: 一定是只考虑速度最大的点,然后,如果两个点所在的位置与速度都

2014多校联合八(HDU 4945 HDU 4946 HDU 4948 HDU 4950 HDU 4951 HDU 4952)

HDU 4945 2048 题意:给你一堆数字  问有几个子集可以拼出2048 思路: 拼数字的规则相当于让数字乘二  所以不是2^i的数字不会拼出2048  那么这些数可选可不选  即为2^cnt种可能 之后只要计算出有几个子集不可能拼出2048即可  不过简单的直接dp是2048*100000的复杂度的  会TLE 所以要变成先枚举元素  再枚举该种元素个数  再枚举2048种状态  然后利用组合求(组合里需要逆元) 为什么这样快?  因为比如枚举2^5这个元素的时候  最多取2^6个  枚

Area of Mushroom HDU - 4946

Area of Mushroom HDU - 4946 题意: 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #include <cmath> 6 using namespace std; 7 8 const int maxn=510; 9 char res[maxn]; 10 struct Node{ 11 int