专栏文章

题解:CF2005B2 The Strict Teacher (Hard Version)

CF2005B2题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqe32bg
此快照首次捕获于
2025/12/04 03:17
3 个月前
此快照最后确认于
2025/12/04 03:17
3 个月前
查看原文

前言

66 篇题解。

分析

我们可以分类讨论,明显发现,只有 David 两侧的老师或者墙有作用。同时,我们要先排序。
接下来我们开始分类讨论。
  • 如果 David 的位置小于最左边的老师,那么他就可以一直往左移动,直到移动到墙,也就是说,在这种情况下,需要 b11b_1-1 步才能抓住 David。
  • 如果 David 的位置大于最右边的老师,那么他就可以一直往右移动,直到移动到墙,也就是说,在这种情况下,需要 nbmn-b_m 步才能抓住 David。
  • 如果 David 的左边和右边都有老师,直到离的最近老师两面包夹,也就是说,在这种情况下,需要 (brbl)÷2(b_r-b_l)\div2 步才能抓住 David。这里的 ll 代表离 David 最近且在左边的老师的编号,rr 代表离 David 最近且在右边的老师的编号。这个过程可以用二分。

好东西

你可以不用手写二分,因为 C++ 里面自带了两个二分函数 lower_bound 和 upper_bound。
  • lower_bound 能查找第一个小于你查找数字的地址符。
  • upper_bound 能查找第一个大于等于你查找的数字的地址符。

注意

一定要搞清楚 n,mn,m 代表者什么,不要搞混 n,mn,m就因为这个我调了半小时。

代码

CPP
//By xiaozhou001
#include<bits/stdc++.h>
using namespace std;
int t,n,m,q,b,a[100007];
int main()
{
    cin>>t;
    while(t--){
        cin>>n>>m>>q;
        for(int i=1;i<=m;i++){
            cin>>a[i];
        }
        sort(a+1,a+1+m);
        for(int i=1;i<=q;i++){
            cin>>b;
            if(b<a[1]){
                cout<<a[1]-1<<endl;
            }else if(b>a[m]){
                cout<<n-a[m]<<endl;
            }else{
                int l=lower_bound(a+1,a+1+m,b)-a;
				int r=upper_bound(a+1,a+1+m,b)-a-1;
                cout<<abs(a[r]-a[l])/2<<endl;
            }
        }
    }
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...