题目描述
背景
CzyCzy 找到宝藏获得屠龙宝刀和神秘秘籍!现在他要去找经常 ntrntr他的JmarsJmars报仇……
题目描述
CzyCzy学会了一招“堕天一击”,他对一个地点发动堕天一击,地面上就会留下一个
很大的圆坑。圆坑的周围一圈能量太过庞大,因此无法通过。所以每次czyczy发动技能都会把地面分割。JmarsJmars 拥有好大好大的土地,几十眼都望不到头,所以可以假设土地的大小是无限大。现在 czyczy 对他发动了猛烈的攻击,他想知道在泽宇攻击之后他的土地被切成几份了?
CzyCzy毕竟很虚,因此圆心都在 x 坐标轴上。另外,保证所有圆两两之间不会相交。
格式
输入第一行为整数 nn,表示 放了 nn 次堕天一击。
接下来 n 行,每行两个整数 。表示在坐标(x[i],0)(x[i],0)放了一次堕天一击,半
径为 r[i]r[i]。
输出一行,表示地面被分割成几块。
数据范围
对于 30%数据,
n≤5000n≤5000
对于 100%数据,
1≤n<=300000,−109≤x[i]≤109,1≤r[i]≤1091≤n<=300000,−109≤x[i]≤109,1≤r[i]≤109.
题目解法
这道题实在没有什么高级解法,一个栈就可以解决。
具体想法就是由于所有的圆都在一条线上,所以,我们可以研究出:
- 一般来说一个圆就是一个贡献
- 如果一个圆被几个圆内切了,也就是说,从一个范围[l,r][l,r]的圆说,如果有若干个[l,p1],[p1,p2],....,[pn,r][l,p1],[p1,p2],....,[pn,r]的圆,那么会产生额外的贡献。
- 我们的目标是找到额外的贡献与不重叠的圆的数量
基于此,我们可以模拟出一个过程。然而这一个过程需要从最左边的最大的圆开始,所以我们先排一个序。
排完序后,从最左边的一个圆开始入栈,那么入栈规则如下:
- 如果栈内是空的,直接入栈
- 栈内的元素始终保持为将来可能有贡献的,也就是将来可能被其它圆填满,为了达到这一点,我们需要:
- 把圆的圆心与半径转化为圆的范围[l,r][l,r]。
- 放入一个元素时比较当前栈顶元素的范围,如果与栈顶的元素有着相同的左端点,那么栈顶元素继续可能被填满。不用删除,只需把栈顶元素的范围缩小,即栈顶元素的ll变成将加入的元素的,然后加入当前元素。
- 如果将加入的元素的范围 ⊊⊊ 栈顶元素的范围,那么栈顶元素弹出,继续比较下一层的元素。
- 如果该元素范围∩∩栈顶元素范围=∅=∅ 那么栈顶元素弹出,继续比较下一层的元素。
- 如果该元素范围在栈顶元素的左边,那么加入当前元素。
分析了这么多,代码也很好理解了
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int _ =320031;
struct sta{
LL ld,rd;
}stk[_];
int n,top;
struct cir{
LL o,r;
}c[_];
bool operator == (cir a,cir b){
return (a.o==b.o)&(a.r==b.r);
}
bool cmp(cir a,cir b){
if(a.o-a.r!=b.o-b.r){
return a.o-a.r<b.o-b.r;
}
return a.o+a.r>b.o+b.r;
}
int main(){
freopen("god.in","r",stdin);
freopen("god.out","w",stdout);
ios::sync_with_stdio(false);
cin>>n;
for(register int i=1;i<=n;++i){
cin>>c[i].o>>c[i].r;
}
sort(c+1,c+n+1,cmp);
register int ans=1;
for(register int i=1;i<=n;++i){
if(c[i]==c[i-1])continue;
++ans;
register LL ld=c[i].o-c[i].r,rd=c[i].o+c[i].r;
while(top){
if(stk[top].ld==ld&&stk[top].rd==rd){
top--;
++ans;
break;
}
if(stk[top].ld==ld){
stk[top].ld=rd;
break;
}
if(ld>=stk[top].rd||(ld>stk[top].ld&&rd<stk[top].rd)){--top;}
else break;
}
stk[++top].ld=ld,stk[top].rd=rd;
}
cout<<ans;
}

探讨一个关于使用圆坑分割无限大地的问题,利用栈的数据结构进行高效求解。问题中,角色Czy释放名为“堕天一击”的技能,在x轴上形成圆坑,这些圆坑将土地分割成若干部分。文章提供了解决方案,包括输入输出格式及算法实现。
461

被折叠的 条评论
为什么被折叠?



