sgu253:Theodore Roosevelt(扫描线)

来源:互联网 发布:为什么淘宝上苹果便宜 编辑:程序博客网 时间:2024/05/19 12:13

题目大意:
      给出n(n105)个点的凸包以及另外m(m105)个点,以及一个不大于m的非负整数k,如果至少有k个点在凸包内,输出YES,否则NO

分析:
      想了半天才想到是扫描线…
      把所有的点排序,从左往右扫,记录当前扫描线处的凸包上下界限,判断点是否在这个范围内即可。

AC code:

#include <cstdio>#include <cmath>#include <map>#include <algorithm>#define cx first#define cy second#define mp make_pair#define eps 1e-8#define is_zero(p) ((p) >= -eps && (p) <= eps)typedef double DB;using namespace std;const int MAXN = 1e5+9;const int MAXM = 1e5+9;int n, m, k;map< pair<int,int>,int > Map;struct pot{    DB x, y;    pot(DB tx=0, DB ty=0):x(tx),y(ty){}    friend bool operator < (const pot &a, const pot &b)    {        return a.x < b.x-eps || (is_zero(a.x-b.x) && a.y < b.y-eps);    }}cvx[MAXN], other[MAXN];int pre[MAXN][2], suf[MAXN][2];pair<pot, int> node[MAXN+MAXM];int sign(DB x){    if(x < -eps) return -1;    else return x > eps;    }DB fx(const pot &a, const pot &b, DB p){    DB ret;    if(is_zero(b.x-a.x)) return 1e10;    ret = (p-a.x)/(b.x-a.x)*(b.y-a.y)+a.y;    return ret;}void make_pre(int l, int r){    int now = r;    while(now != l)    {        pre[now][0] = now%n+1;        suf[now%n+1][0] = now;        now = now%n+1;      }    now = r;    while(now != l)    {        pre[now][1] = (now-2+n)%n+1;        suf[(now-2+n)%n+1][1] = now;        now = (now-2+n)%n+1;    }}int main(){    #ifndef ONLINE_JUDGE    freopen("input.txt", "r", stdin);    freopen("output.txt", "w", stdout);    #endif    scanf("%d%d%d", &n, &m, &k);    int ru = 0, ld = 0, tot = 0;    for(int i = 1; i <= n; ++i)    {        int x, y;        scanf("%d%d", &x, &y);        cvx[i] = pot(x, y);        node[++tot] = mp(cvx[i], i);        Map[mp(x, y)] = i;        if(!ru || cvx[ru] < cvx[i]) ru = i;        if(!ld || cvx[i] < cvx[ld]) ld = i;    }    make_pre(ld, ru);    int sum = 0;    for(int i = 1; i <= m; ++i)    {        int x, y;        scanf("%d%d", &x, &y);        other[i] = pot(x, y);        if(Map.find(mp(x, y)) != Map.end()) sum++;        else node[++tot] = mp(other[i], 0);    }    sort(node+1, node+n+m+1);    bool in = false;    int up, down;    for(int i = 1; i <= n+m; ++i)    {        int id = node[i].cy;        pot now = node[i].cx;        if(!id)        {            if(in)            {                DB h1 = fx(cvx[up], cvx[suf[up][0]], now.x), h2 = fx(cvx[down], cvx[suf[down][1]], now.x);                if(h1 > 1e9) {if(sign(cvx[suf[up][0]].y-now.y) >= 0) sum++;}                else if(h2 > 1e9) {if(sign(cvx[suf[down][1]].y-now.y) >= 0) sum++;}                else if(sign(now.y-h2) >= 0 && sign(h1-now.y) >= 0) sum++;            }        }        else         {            if(id == ld) in = true, up = down = id;            else            {                if(id == ru) break;                if(pre[id][0] == up) up = id;                else down = id;            }        }    }    if(sum >= k) puts("YES");    else puts("NO");    #ifndef ONLINE_JUDGE    fclose(stdin);    fclose(stdout);    #endif    return 0;   }
0 0
原创粉丝点击