1 条题解
-
0
自动搬运
来自洛谷,原作者为

jimmywang
基环内向树,二维前缀和,三碳化四铝,闪电五连鞭搬运于
2025-08-24 21:56:20,当前版本为作者最后更新于2020-05-01 09:49:43,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
此题,
其实简化一下题目,就是在从到里找一个最小值,并把它去掉,再算剩下的几个数的平均值,求是这个平均值最大的
那么,其实就是部分:最小值、平均数、求平均数最大值。
一个一个看:
最小值的朴素解法是什么?扫一遍啊
但是我们还要遍历一次从到,而且如果求平均值也是的话,总的来说就是了,绝对爆炸。
想一想,我们不用每次都求最小值啊,一开始就预处理掉不就好了,反正是静态的
于是就有了这份代码:
for(int i=n;i>=2;i--)mn[i]=min(mn[i+1],a[i]);就这么一行?
对,就这么一行。
这样,我们就能求最小值啦~~
平均值。。。
要求平均值,就要知道一个区间的和
和最小值一样,朴素的方法是的
但是我们还要遍历一次从到,总的来说又是了,还是炸了。
但是我们有什么?前缀和啊!
而且这里还不用前缀和,只要倒着一个一个加,还能合并到上面最小值代码里
于是就是这样了:
for(int i=n;i>=2;i--)mn[i]=min(mn[i+1],a[i]),sum[i]=sum[i+1]+a[i];就这么一行?
对,还是就这么一行。
于是,求平均值也啦~~
其实平均数也能与处理啊,就是
(sum[i]-min[i])/(n-i)嘛
于是就是这样了:
for(int i=n;i>=2;i--){ mn[i]=min(mn[i+1],a[i]); sum[i]=sum[i+1]+a[i]; if(i!=n)avr[i]=(sum[i]-mn[i])/(double)(n-i); }再就是比较了,此处不再说明。
完整代码:
#include<algorithm> #include<bitset> #include<cmath> #include<cstdio> #include<cstring> #include<map> #include<iostream> #include<queue> #include<set> #include<stack> #include<string> #include<vector> using namespace std; #define ll long long #define f(i,a,b) for(int i=a;i<=b;i++) inline ll read(){ int s=0,w=1; char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();} while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar(); return s*w; } #define d read() ll n; double a[1000010]; double avr[1000010]; double sum[1000010]; double mn[1000010]; double mx; int main(){ n=d; f(i,1,n+1)mn[i]=10010; f(i,1,n)scanf("%lf",&a[i]); for(int i=n;i>=2;i--){ mn[i]=min(mn[i+1],a[i]); sum[i]=sum[i+1]+a[i]; if(i!=n)avr[i]=(sum[i]-mn[i])/(double)(n-i); } f(i,2,n-1)mx=max(mx,avr[i]); f(i,2,n-1)if(mx==avr[i])printf("%lld\n",i-1); return 0; }
- 1
信息
- ID
- 3044
- 时间
- 1000ms
- 内存
- 125MiB
- 难度
- 3
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者