Mummy Madness
Mummy Madness
你打开了一个埃及古墓,木乃伊们从几千年的沉睡中惊醒,变得十分暴躁。
沙漠看做一个无限大的网格,你在
每一个时刻,你可以向周围的八个方向任意移动一格,或者保持不动。然后所有木乃伊会向着离你欧几里得距离最近的方向移动一格。
你最长可以坚持到什么时刻不被木乃伊抓住?若你可以永远不被抓住,输出never。
Solution
题目二次翻译:
给定平面上n个点,假设当前答案为ans
对每个点构造一个(x-ans,y-ans)-(x+ans,y+ans)的正方形
如果当前构造的所有矩形的并能将(-ans,-ans)-(ans,ans)
全部包含,则称当前答案可行,最小化ans
对于每一个矩形,将其端点
(x-ans,y-ans)->(max(x-ans,-ans),max(y-ans,-ans))
(x+ans,y+ans)->(min(x+ans,ans),min(y+ans,ans))
然后我们用扫描线维护矩形面积并
当前答案可行等价于
然后这题就做完了
注意:代码中由于扫描线维护的区间左闭右开,所以在第二个端点处的x,y均需要++
然后就是 臭名昭著 喜闻乐见的离散化环节了
然后这题就做完了
话说这题怎么做应该是
LD只给8s???
Code:
#include <bits/stdc++.h> #define ls (x<<1) #define rs (x<<1|1) const int N=1e5+5; using namespace std; int n,T; struct Tree{ int l,r,cnt,len; }t[N<<2]; struct Line{ int l,r,y,val; bool operator <(const Line &L)const{ return y<L.y; } }; int x[N],y[N]; vector<int> a; vector<Line> Q; void pushup(int x) { t[x].len=0; if(t[x].cnt) { t[x].len=a[t[x].r]-a[t[x].l]; } else if(t[x].l+1<t[x].r) t[x].len=t[ls].len+t[rs].len; } void build(int x,int l,int r) { t[x].len=t[x].cnt=0; t[x].l=l,t[x].r=r; if(l+1>=r)return ; int mid=l+r>>1; build(ls,l,mid); build(rs,mid,r); } void upd(int x,int ll,int rr,int val) { if(ll<=t[x].l&&t[x].r<=rr) { t[x].cnt+=val; pushup(x); return ; } int mid=t[x].l+t[x].r>>1; if(ll<mid)upd(ls,ll,rr,val); if(mid<rr)upd(rs,ll,rr,val); pushup(x); } bool check(int mid) { long long sum=0,range=mid; Q.clear(); a.clear(); for(int i=1,x1,x2,y1,y2;i<=n;i++) { x1=max(-range,x[i]-range),x2=min(range+1,x[i]+range+1); y1=max(-range,y[i]-range),y2=min(range+1,y[i]+range+1); //cout<<x1<<" "<<x2<<"--"<<y1<<" "<<y2<<"\n"; if(x1<x2&&y1<y2) { Q.push_back((Line){x1,x2,y1,1}); Q.push_back((Line){x1,x2,y2,-1}); a.push_back(x1); a.push_back(x2); } } sort(Q.begin(),Q.end()); sort(a.begin(),a.end()); a.erase(unique(a.begin(),a.end()),a.end()); int tot=a.size(),sz=Q.size(); build(1,0,tot-1); for(int i=0;i<sz;i++) { int L=lower_bound(a.begin(),a.end(),Q[i].l)-a.begin(),R=lower_bound(a.begin(),a.end(),Q[i].r)-a.begin(); upd(1,L,R,Q[i].val); while(i<sz-1&&Q[i+1].y==Q[i].y) { i++; L=lower_bound(a.begin(),a.end(),Q[i].l)-a.begin(),R=lower_bound(a.begin(),a.end(),Q[i].r)-a.begin(); upd(1,L,R,Q[i].val); } if(i<sz-1) { sum+=1ll*(Q[i+1].y-Q[i].y)*t[1].len; //cout<<"high: "<<Q[i+1].y<<"-"<<Q[i].y<<" \nlen:"<<t[1].len<<"\n"; } } range=range<<1|1; //cout<<"range:"<<range<<" "<<sum<<"="<<range*range<<"\n"; return sum==range*range; } void work() { for(int i=1;i<=n;i++) { scanf("%d%d",&x[i],&y[i]); } int l=1,r=1e6,ans=-1; while(l<=r) { int mid=l+r>>1; if(check(mid)) { ans=mid; r=mid-1; } else { l=mid+1; } } printf("Case %d: ",++T); if(~ans) { printf("%d\n",ans); } else { printf("never\n"); } } int main() { //freopen("madness.in","r",stdin); //freopen("madness.out","w",stdout); while(cin>>n) { if(n==-1)break; work(); } return 0; }