zoukankan      html  css  js  c++  java
  • hdu 4946

    Area of Mushroom

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
    Total Submission(s): 4560    Accepted Submission(s): 1009


    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
     
    析:有n个学生,再平面上左标为(xi,yi),且有一个速度vi,现在想知道每一个学生是否可以达到平面上的无穷点比其他学生快。
      要想最快达到平面上的其他点,速度必定是最大的才能达到,而且不能被其他点所包围,发现在凸包上的点满足次要求,故首先求出最大速度的点,然后对最大速度点求凸包。
      注意:对于位置相同且速度相同的点由于被对方相互限制,所以无论如何也不能满足要求,也就是速度等价于0,而且如果最大速度就是0,那么直接输出全0即可
     
    #include <math.h>
    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #define ll long long
    using namespace std;
    const int N = 1005;
    int t, n, m, ans;
    int top, s[N];
    struct Point{
        double x, y, v;
        int id;
        bool operator<(const Point &a)const{
            if(y == a.y)
                return x < a.x;
            return y < a.y;
        }
        bool isEqual(Point a){
            return (x == a.x && y == a.y && v == a.v);
        }
        double getCross(Point a, Point b){
            return (a.x-x)*(b.y-y)-(a.y-y)*(b.x-x);
        }
    }p[N], tmp[N], stk[N];
    
    void Graham(int cnt){
        top = 1;
        sort(tmp, tmp+cnt);
        if(!cnt){
            top = 0;
            return;
        }
        stk[0] = tmp[0];
        if(cnt == 1){
            top = 1;
            return;
        }
        stk[1] = tmp[1];
        if(cnt == 2){
            top = 2;
            return;
        }
        for(int i = 2; i < cnt; i ++){
            while(top && stk[top-1].getCross(stk[top], tmp[i]) < 0)
                top--;
            stk[++top] = tmp[i];
        }
        int len = top;
        stk[++top] = tmp[cnt-2];
        for(int i = cnt-3; i+1; i --){
            while(top != len && stk[top-1].getCross(stk[top], tmp[i]) < 0)
                top--;
            stk[++top] = tmp[i];
        }
    }
    int main(){
        ans = 1;
        while(scanf("%d", &n) && n){
            double Max = 0;
            for(int i = 0; i < n; i ++){
                scanf("%lf%lf%lf", &p[i].x, &p[i].y, &p[i].v);
                p[i].id = i;
                Max = max(Max, p[i].v);
            }
            printf("Case #%d: ", ans++);
            if(Max == 0){
                for(int i = 0; i < n; i ++){
                    printf("0");
                }
                printf("
    ");
                continue;
            }
            for(int i = 0; i < n-1; i ++){
                for(int j = i+1; j < n; j ++){
                    if(p[i].isEqual(p[j])){
                        p[j].v = 0;
                        s[i] = s[j] = -1;
                    }
                }
            }
            int cnt = 0;
            for(int i = 0; i < n; i ++){
                if(p[i].v == Max){
                    tmp[cnt++] = p[i];
                }
            }
            Graham(cnt);
            for(int i = 0; i < top; i ++){
                if(s[stk[i].id] != -1){
                    s[stk[i].id] = 1;
                }
            }
            for(int i = 0; i < n; i ++){
                printf("%d", s[i] > 0);
                s[i] = 0;
            }
            printf("
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    May LeetCoding Challenge22 之 比较器comparator、map按Value排成逆序、桶排序
    May LeetCoding Challenge21 之 动态规划的min使用
    May LeetCoding Challenge20 之 二叉树中序遍历
    May LeetCoding Challenge19 之 单调栈2.0
    May LeetCoding Challenge18 之 滑动窗口2.0
    May LeetCoding Challenge17 之 滑动窗口
    May LeetCoding Challenge16 之 链表重组
    APT常用命令
    DDCTF-misc-流量分析
    Wireshark学习笔记
  • 原文地址:https://www.cnblogs.com/microcodes/p/12815040.html
Copyright © 2011-2022 走看看