zoukankan      html  css  js  c++  java
  • 【BZOJ 3958】 3958: [WF2011]Mummy Madness (二分+扫描线、线段树)

    3958: [WF2011]Mummy Madness

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 96  Solved: 41

    Description

    在2011年ACM-ICPC World Finals上的一次游览中,你碰到了一个埃及古墓。
    不幸的是,你打开了坟墓之后,才发现这是一个坏主意:突然之间,原本空无一物的沙漠上已经爬满了暴躁的木乃伊。(如果你也沉睡几千年而突然被惊醒,你也会变得如此暴躁的。)(幸运的是,当你做完这道题的时候,你醒来了,发现你在弗罗里达的酒店里。那些木乃伊只是一场梦。)
    面对这一大堆疯狂的木乃伊,你唯一的机会就是试图在他们抓到你之前逃跑。问题是:假如你与木乃伊永不疲倦,那么经过多长时间你会被木乃伊抓到?
    我们把沙漠看成一个正方形的网格,你与木乃伊轮流移动(你走出第一步)。轮到你时,你可以移动到相邻的8个格子之一,或者站着不动。轮到木乃伊时,每个木乃伊会移动到其相邻的格子之一,使得他与你的欧几里得距离尽量小(假设你与木乃伊都站在格子的中心位置)。允许多个木乃伊同时占据同一个格子。
    在每个单位时间内,你先做出移动,然后木乃伊做出移动。如果你与任何一个木乃伊站在同一位置,你会被抓住。当然,你试图尽量长时间避免被抓住。经过多少单位时间你会被抓住呢?
    下图描述了你被4个木乃伊追逐的例子。H代表你的初始位置,而M代表木乃伊的初始位置。以你的初始位置为原点,则经过4个单位时间后,你被初始位置为(3,4)的木乃伊抓住。

    Input

    输入文件包含若干组数据。每组数据的第一行为一个数n(0≤n≤10^5),表示沙漠中木乃伊的个数。接下来n行,每行两个整数x y,表示初始时在(x,y)有一个木乃伊。x,y的绝对值均不超过10^6。你的初始位置是(0,0),保证一开始这里没有木乃伊。
    输入文件以一行-1结束。

    Output

    对于每组测试数据,输出一行,包括它的编号和被抓住经过的最长时间(即你做出决策的次数);或输出"never",如果你有办法永远不被抓住。
    请以样例输出的格式输出数据。

    Sample Input

    4
    -3 5
    3 4
    -6 -2
    1 -5
    1
    0 -1
    -1

    Sample Output

    Case 1: 4
    Case 2: never

    HINT

    对于100%的数据,n≤10^5

    Source

    【分析】

      我不会做。。膜奥爷爷。。

      二分【显然可以】走多少步,然后把人和木乃伊能走的范围【是矩形】画出来,然后如果木乃伊们能走的范围完全覆盖了人能走的范围,那么就会被赶尽杀绝了!!

      然后就线段树做扫描线。。具体看之前的博客:http://www.cnblogs.com/Konjakmoyu/p/6050343.html

      wohenshuai说得对,不要随便离散化【但是我还是离散化了】,不然很容易错。。

      然后,只做询问的区间,不然很容易T【我已经T了3、4遍了,卡评测

      1 #include<cstdio>
      2 #include<cstdlib>
      3 #include<cstring>
      4 #include<iostream>
      5 #include<algorithm>
      6 using namespace std;
      7 #define Maxn 100010
      8 
      9 int mymin(int x,int y) {return x<y?x:y;}
     10 int mymax(int x,int y) {return x>y?x:y;}
     11 
     12 struct node{int x,y;}t[Maxn];
     13 struct hp{int l,r,h,f;}w[Maxn*6];
     14 struct lsh{int x,id;}ls[Maxn*6];
     15 bool cmp(lsh x,lsh y) {return x.x<y.x;}
     16 bool cmp2(hp x,hp y) {return (x.h==y.h)?(x.f>y.f):(x.h<y.h);}
     17 int n;
     18 
     19 struct nnode
     20 {
     21     int l,r,lc,rc,cnt;
     22     bool p;
     23 }tr[Maxn*20];
     24 
     25 int tot;
     26 int build(int l,int r)
     27 {
     28     int x=++tot;
     29     tr[x].l=l;tr[x].r=r;
     30     tr[x].cnt=0;tr[x].p=0;
     31     if(l!=r)
     32     {
     33         int mid=(l+r)>>1;
     34         tr[x].lc=build(l,mid);
     35         tr[x].rc=build(mid+1,r);
     36     }
     37     else tr[x].lc=tr[x].rc=0;
     38     return x;
     39 }
     40 
     41 void upd(int x)
     42 {
     43     if(tr[tr[x].lc].p&&tr[tr[x].rc].p) tr[x].p=1;
     44     else if(tr[x].cnt>0) tr[x].p=1;
     45     else tr[x].p=0;
     46 }
     47 
     48 void change(int x,int l,int r,int y)
     49 {
     50     if(tr[x].l==l&&tr[x].r==r)
     51     {
     52         tr[x].cnt+=y;
     53         upd(x);
     54         return;
     55     }
     56     int mid=(tr[x].l+tr[x].r)>>1;
     57     if(r<=mid) change(tr[x].lc,l,r,y);
     58     else if(l>mid) change(tr[x].rc,l,r,y);
     59     else
     60     {
     61         change(tr[x].lc,l,mid,y);
     62         change(tr[x].rc,mid+1,r,y);
     63     }
     64     upd(x);
     65 }
     66 
     67 int query(int x,int l,int r)
     68 {
     69     if(tr[x].p) return 1;
     70     if(tr[x].l==l&&tr[x].r==r) return tr[x].p;
     71     int mid=(tr[x].l+tr[x].r)>>1;
     72     if(r<=mid) return query(tr[x].lc,l,r);
     73     else if(l>mid) return query(tr[x].rc,l,r);
     74     else return (query(tr[x].lc,l,mid)&&query(tr[x].rc,mid+1,r));
     75 }
     76 
     77 bool check(int nw)
     78 {
     79     w[1].l=-nw;w[1].r=nw;w[1].h=-nw;w[1].f=-3;
     80     w[2].l=-nw;w[2].r=nw;w[2].h=nw;w[2].f=-2;
     81     int wl=2;
     82     for(int i=1;i<=n;i++)
     83     {
     84         if(t[i].y+nw<-nw||t[i].y-nw>nw) continue;
     85         if(t[i].x+nw<-nw||t[i].x-nw>nw) continue;
     86         w[++wl].l=mymax(-nw,t[i].x-nw);w[wl].r=mymin(t[i].x+nw,nw);w[wl].h=t[i].y-nw;w[wl].f=1;
     87         if(t[i].y+nw<=nw) {w[++wl].l=mymax(t[i].x-nw,-nw);w[wl].r=mymin(t[i].x+nw,nw);w[wl].h=t[i].y+nw+1;w[wl].f=-1;}
     88     }
     89     int sl=0;
     90     for(int i=1;i<=wl;i++) {ls[++sl].x=w[i].l,ls[sl].id=i;ls[++sl].x=w[i].r;ls[sl].id=-i;}
     91     sort(ls+1,ls+sl+1,cmp);
     92     int p=1;
     93     if(ls[1].id>0) w[ls[1].id].l=1;
     94     else w[-ls[1].id].r=1;
     95     for(int i=2;i<=sl;i++)
     96     {
     97         if(ls[i].x!=ls[i-1].x)
     98         {
     99             // p++;
    100             if(ls[i].x-ls[i-1].x==1) p++;
    101             else p+=2;
    102         }
    103         if(ls[i].id>0) w[ls[i].id].l=p;
    104         else w[-ls[i].id].r=p;
    105     }
    106     sort(w+1,w+1+wl,cmp2);
    107     tot=0;
    108     build(1,p);
    109     bool ok=1;
    110     int asl=-1,asr;
    111     for(int i=1;i<=wl;i++)
    112     {
    113         if(w[i].f==-3) asl=w[i].l,asr=w[i].r;
    114         if(w[i].f!=-2&&w[i].f!=-3) change(1,w[i].l,w[i].r,w[i].f);
    115         if(asl!=-1&&!tr[1].p) {ok=0;break;}
    116         if(w[i].f==-2) break;
    117     }
    118     return ok;
    119 }
    120 
    121 void ffind(int l,int r)
    122 {
    123     int ans=-1;
    124     while(l<=r)
    125     {
    126         int mid=(l+r)>>1;
    127         if(check(mid)) ans=mid,r=mid-1;
    128         else l=mid+1;
    129     }
    130     if(ans==-1) printf("never
    ");
    131     else printf("%d
    ",ans);
    132 }
    133 
    134 int main()
    135 {
    136     int kase=0;
    137     while(1)
    138     {
    139         scanf("%d",&n);
    140         if(n==-1) break;
    141         for(int i=1;i<=n;i++) scanf("%d%d",&t[i].x,&t[i].y);
    142         printf("Case %d: ",++kase);
    143         ffind(1,1000000);
    144     }
    145     return 0;
    146 }
    View Code

    2017-03-28 19:21:43

  • 相关阅读:
    最大化等比例测试演化Demo-传统方法
    Layout-3相关代码:3列布局代码演化三]
    Layout-3相关代码:3列布局代码演化[二]
    Layout-2相关代码:3列布局代码演化[一]
    Layout-1相关代码
    【比赛打分展示双屏管理系统-专业版】Other.ini 配置文件解读以及排行榜界面及专家评语提交展示等具体配置
    Android 开源简单控件
    Android Drawable资源
    Android Service与Thread的区别
    Android事件处理
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/6636458.html
Copyright © 2011-2022 走看看