专栏文章
题解:AT_abc391_d [ABC391D] Gravity
AT_abc391_d题解参与者 7已保存评论 9
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @miqcxxis
- 此快照首次捕获于
- 2025/12/04 02:45 3 个月前
- 此快照最后确认于
- 2025/12/04 02:45 3 个月前
像流星划过夜空,转瞬即逝的梦。
在平面直角坐标系中,有 颗流星(shooting_star)划过,第 颗的初始坐标(第 时刻坐标)为 。保证 。
每一个单位时刻,流星按如下规则运动:
- 如果底部是满的既 的位置上都有流星,那么这些流星在这个时刻末全部消失;否则底部的流星不动。
- 其余不在底部的流星向下移动一个单位。
在看流星的 fyy 想问妳 个问题:询问第 个流星在 时刻末是否存在。
妳非常聪明,很快注意到 很大,不可能一个一个处理,妳打算对于每一个流星,计算它消失的时刻。
如何计算每一个流星消失的时刻?妳很快发现流星消失是一轮一轮的。
考察横向和竖向的变化:
- 横向:妳发现一轮消失的流星总是每一列中最低的一个。
- 纵向:妳发现每一列中,低的流星总不会影响高的流星的运动状态。
以上是一些感性认识,我们现在转化为形式化语言。
-
考虑将流星按列放进优先队列。具体的,初始 放进 。其中 为 个小根堆(优先队列)。
-
取 的队首。
- 如果某个队列空了,那么以后的流星(包括这一轮)永不消失。
- 否则取 的队首 坐标的最大值为这一轮所有流星的消失时间 (注意临界问题,如果一个时刻 那么这一轮的流星都在 时刻消失过了,注意能取等号)。
- 将所有队首出队。
-
不断执行操作 ,直至存在一个空队。
然后代码是很简单的,据笔者所知很多人这道题都死于细节。笔者自认为自己的代码细节很少好理解。
CPPconst int fyy=0;
int main()
{
int N,W;
cin>>N>>W;
vector<priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>> q(W+1);
vector<int> ans(N+1,(int)1e9+24);
rep(i,1,N)
{
int X,Y;
cin>>X>>Y;
q[X].push({Y,i});
}
bool zxq=1; // 张修齐:是否可进行下一轮
while(zxq)
{
int _max=fyy;
rep(i,1,W)
{
if(q[i].empty())
{
zxq=fyy;
break;
}
_max=max(_max,q[i].top().first);
}
if(!zxq) break;
rep(i,1,W)
{
ans[q[i].top().second]=_max;
q[i].pop();
}
}
int Q;
cin>>Q;
while(Q--)
{
int T,A;
cin>>T>>A;
if(T>=ans[A])
cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
}
// 路虽远行则将至,事虽难做则必成。
流星姐姐珂愛喵~
相关推荐
评论
共 9 条评论,欢迎与作者交流。
正在加载评论...