alice132

 

2026.1.10 作业 - # P2390 地标访问

题目背景

改编自 USACO2007Nov 铜组 Exploration

题目描述

贝西在一条道路上旅行,道路上有许多地标,贝西想要在日落之前访问尽可能多的路标。贝西每分钟可以移动一单位距离。

将道路视为一条数轴,贝西从原点出发,道路上有 \(n(1 \le n \le 5\times 10^4)\) 个地标,每个地标有一个坐标 \(x_i(|x_i| \le 10^5)\) 且地标的坐标各不相同,\(t(1 \le t \le 10^9)\) 分钟之后将会日落。

输入格式

第一行:两个整数 \(t,n\)

第二行至第 \(n+1\) 行:地标的坐标 \(x_i\)

输出格式

一个整数,贝西能访问的最多的地标数

输入输出样例 #1

输入 #1

25 14
16
8
-7
3
10
-15
-17
6
-12
14
-13
2
9
-5

输出 #1

8

说明/提示

1、贝西日落时不用回到原点。

2、与原模拟水题不同。

3、数据较原题有所修改

#include <bits/stdc++.h>
#define D 100000
using namespace std;
int T,n,cnt[200002],L,R,s1[200002],s2[200002];
int main(){
    cin>>T>>n;L=0;R=0;
    for (int i=1;i<=n;i++) {
       int x; cin>>x; cnt[x+D]=1;
       L=min(x,L);R=max(x,R);
    }

    s1[D]=s2[D]=cnt[D];
    for (int i=D+1;i<=D+D;i++) s1[i]=s1[i-1]+cnt[i];
    for (int i=D-1;i>=0;i--) s2[i]=s2[i+1]+cnt[i];
    int L1=max(-T,L);
    int R1=min(T,R);

    int Ans=max(s1[D+R1],s2[D+L1]);
    int j=0;
    for (int i=L1;i<=0;i++) {
         if (2*(-i)>T) continue;
         while (j<=R1 && 2*(-i)+j<=T) j++;j--;
         Ans=max(s2[i+D]+s1[j+D],Ans);
    }
    j=0;
    for (int i=R1;i>=0;i--) {
        if (2*i>T) continue;
        while (j<=-L && 2*i+j<=T) j++;j--;
        Ans=max(s1[i+D]+s2[D-j],Ans);
    }
    cout<<Ans<<endl;
   return 0;
}

posted on 2026-01-20 21:53  alice_ss  阅读(0)  评论(0)    收藏  举报

导航