M-数值膨胀之美
题目链接
题目描述🥰
题目思路😀
这道题的赛时数据过于水了,所以在赛事没有仔细想就过了🤡,不过实际上这道题的做法还是蛮值得学习的。
首先我们一开始可能会有一个思想上的误区,我们是不是只需要把最小值*2-最大值再用最大值减最小值就可以得到最小极差了,但是实际上不是的,例如99 100这组数据,如果我们把99*2,极差就是88,而实际上我们可以把99和100都乘以2,就可以得到最小的极差2了,所以这种思路是错的❌
那么怎么去解决这个问题呢,我们可以从最小值开始更新,在区间不断扩大的同时更新答案。
解题步骤:
- 我们需要用一个数组同时记录数组元素和它对应的下标,为了后续区间扩展做准备
- 因为是从最小值开始扩展,所以要sort数组。
- 遍历数组,扩展乘2的区间,在区间扩展的过程中用ma记录扩展完区间的最大值
- 在每一次扩展完都更新一遍答案,每一次的最大值是记录的ma,最小值是乘2区间的最小值和未乘2区间的最小值两者的min值。
- 输出答案
AC代码🧠
// Problem: 数值膨胀之美
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/95323/M
// Memory Limit: 512 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
#define debug1(a) cout << #a << '=' << a << endl;
#define debug2(a, b) cout << #a << " = " << a << " " << #b << " = " << b << endl;
#define debug3(a, b, c) cout << #a << " = " << a << " " << #b << " = " << b << " " << #c << " = " << c << endl;
#define debug4(a, b, c, d) cout << #a << " = " << a << " " << #b << " = " << b << " " << #c << " = " << c << " " << #d << " = " << d << endl;
#define debug5(a, b, c, d, e) cout << #a << " = " << a << " " << #b << " = " << b << " " << #c << " = " << c << " " << #d << " = " << d << " " << #e << " = " << e << endl;
#define vec(a) \
for (int i = 0; i < a.size(); i++) \
cout << a[i] << ' '; \
cout << endl;
#define darr(a, _i, _n) \
cout << #a << ':'; \
for (int ij = _i; ij <= _n; ij++) \
cout << a[ij] << ' '; \
cout << endl;
#define endl "\n"
#define pow pim
int pim(int a,int k)
{
int res=1;
if(a==0)return 0;
while(k)
{
if(k&1)res=(int)res*a;
k>>=1;
a=(int)a*a;
}
return res;
}
#define fi first
#define se second
#define caseT \
int T; \
cin >> T; \
while (T--)
#define int long long
// #define int __int128
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
const double PI = acos(-1.0);
const int INF = 0x3f3f3f3f;
const int MOD = 99999999;
// const int N = ;
void solve()
{
int n;
cin>>n;
vector<int>a(n);
vector<PII>b(n);
for(int i=0;i<n;i++)
{
cin>>a[i];
b[i].first=a[i];
b[i].second=i;
}
sort(b.begin(),b.end());
b[n].first=2e9;
int l=b[0].second;
int r=b[0].second;
int ma=max(b[0].first*2,b[n-1].first);//求出初始的最大值
int res=ma-min(b[0].first*2,b[1].first);
for(int i=1;i<n;i++)
{
while(b[i].second<l)
{
l--;
ma=max(a[l]*2,ma);
}
while(b[i].second>r)
{
r++;
ma=max(a[r]*2,ma);
}
//更新极差的答案值
//因为极差的定义是当前区间的最大值减最小值,所以是ma-min(b[0].first*2,b[i+1].first)
res=min(res,ma-min(b[0].first*2,b[i+1].first));
}
cout<<res<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
// caseT
solve();
return 0;
}
/*
*/
标签:
算法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】