P7996 题解
原题链接。
前置知识:
方差计算公式。
题目大意:
给你一段序列和一个值
分析:
根据数学原理,如果一个数
我们可以先求出原序列的方差
code:
#include<bits/stdc++.h>
#define I using
#define her std
#define ll long long
#define Love namespace
#define very_much ;
I Love her very_much//防伪
const int maxn=7*1e6+5;
ll n,m,k;
double p=0,s=0;
double a[maxn];
double minn=1e21;//需赋极大值
ll read()
{
ll 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<<1)+(x<<3)+(ch^48);ch=getchar();}
return x*f;
}
int main()
{
n=read(),k=read();
for(int i=1;i<=n;i++) a[i]=read();
sort(a+1,a+1+n);//排序进行特判
if(a[1]==a[n]) //如果最大值等于最小值,显然方差为0
{
printf("No answer!");
return 0;
}
for(int i=1;i<=n;i++) p+=a[i];
p/=n;
for(int i=1;i<=n;i++) s+=(a[i]-p)*(a[i]-p);
s/=n;//计算出原方差
ll ans=sqrt(k/s);//求出可能的最优值
for(double i=max(1.0,ans-6.0);i<=ans+6.0;i+=1.0)//最优值会在一定范围内波动
{
if(abs(s*i*i-k)<minn)//如果此时的i会使s更接近k
{
minn=abs(s*i*i-k);//进行替换
ans=i;
}
}
printf("%lld",ans);//输出
}