【题解】CF1413C Perform Easily(双指针)
【题解】CF1413C Perform Easily
写篇题解水水经验~顺便增加一下 RP~
比较套路和简单的一道绿题。
题目链接
Perform Easily - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题意概述
给你一个长度为
数据范围
思路分析
首先考虑处理后数组的最大和最小值,一定是对于所有的
那么我们把对于每个 vector
里。为了确定 vector
中的每一个数是哪个 vector
中的每个元素都规定一个
那么问题实际上就转化为:
有一个长度为
的数组,且每个元素都有一个 ,现在让你从这个数组里面选择一些数,要求:
- 对于所有的
,要求选出来的数中至少有一个数的 。 - 选出来的数在所有合法的选择方案中,极差最小。
定义这个 vector
为
因为要求的是极差最小,那实际上就是让我们确定选出来数的最大值和最小值。那么想到枚举最小值,那么我们只需要考虑当
由于题目要求的是极差,我们联想到可以将这个 vector
中的元素排序。
所以当
也就是说当
到目前为止我们已经有了一个做法了:枚举
但是这样做复杂度是
我们发现枚举
有了单调不降这个特征,我们就可以愉快的使用双指针了,直接用双指针维护当前最小值和最大值的位置
时间复杂度
代码实现
代码
//CF1413C
//The Way to The Terminal Station…
#include<cstdio>
#include<iostream>
#include<vector>
#include<algorithm>
#define pii pair<int,int>
#define mk make_pair
#define int long long
using namespace std;
const int maxn=1e6+10;
int b[maxn],a[10],cntnow[maxn];
vector<pii>p;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int cmp(pii a,pii b){return a.first<b.first;}
signed main()
{
for(int i=1;i<=6;i++)a[i]=read();
int n=read();
for(int i=1;i<=n;i++)
{
b[i]=read();
for(int j=1;j<=6;j++)p.push_back(mk(b[i]-a[j],i));
}
sort(p.begin(),p.end(),cmp);
int r=-1;
int ans=1e18;
int now=0;
for(int l=0;l<p.size();l++)
{
while((r<(signed)p.size()-1)&&now<n)
{
r++;
cntnow[p[r].second]++;
if(cntnow[p[r].second]==1)now++;
}
if(now>=n)ans=min(ans,p[r].first-p[l].first);
cntnow[p[l].second]--;
if(cntnow[p[l].second]==0)now--;
}
cout<<ans<<'\n';
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下