B.北境之都 (前缀+后缀)枚举 二分 1s

在遥远的北方有一个国家,这个国家有一个房地产商,他新盖的小区里有n座楼房他准备通过这个小区大赚一笔。

但是国王胖赤耳颁布了一条奇怪的法令:一个小区中任意两个房子的高度差必须要小于等于M米。因此房地产商必须要调整房子的高度,使得任意两个房子的高度差均小于等于M米。每个房子只能改变一次高度,将一个房子的高度改变k米的花费是k^2万元,求房地产商最低要花费多少万元。
输入描述

输入第一行包含两个整数n,m(n,m <= 2e5)

接下来一行包含n个整数,分别代表每一个房子的高度(1≤h≤2e5)。

输出描述

输出一行一个整数代表房地产商的最低花费。

n=4 m=23
40 21 44 46

2
数据范围 n,m=2e5 不能2重循环
完全平方公式展开 求前缀和+平方前缀和即可
注意n,m,p,q 用ll 否则乘积会爆int

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>

using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=2e5+5;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[maxn],prea[maxn],prea2[maxn],sufa[maxn],sufa2[maxn];
int main()
{
	ios::sync_with_stdio(false);
	ll n,m;
	ll ans=inf;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
		cin>>a[i];
	sort(a+1,a+n+1);
	prea[0]=0;
	for(int i=1;i<=n;i++)
	{
		prea[i]=prea[i-1]+a[i];
	}
	prea2[0]=0;
	for(int i=1;i<=n;i++)
	{
		prea2[i]=prea2[i-1]+a[i]*a[i];
	}
	sufa[n+1]=0;
	for(int i=n;i>=1;i--)
	{
		sufa[i]=sufa[i+1]+a[i]; 
	}
	sufa2[n+1]=0;
	for(int i=n;i>=1;i--)
	{
		sufa2[i]=sufa2[i+1]+a[i]*a[i]; 
	}
	for(ll i=a[1];i<=a[n];i++)
	{
		ll p=lower_bound(a+1,a+n+1,i)-a;//第一个大于等于
		ll q=upper_bound(a+1,a+n+1,i+m)-a-1;//第一个大于 最后一个小于等于 
	//	cout<<p<<" "<<q<<endl;
		ll qian=(p-1)*i*i-2*i*prea[p-1]+prea2[p-1];
		ll hou=(n-q)*(i+m)*(i+m)-2*(i+m)*sufa[q+1]+sufa2[q+1];
	//	cout<<qian<<" "<<hou<<endl;
		ans=min(ans,qian+hou);
	}
	cout<<ans<<endl;
	return 0;
} 

超时写法 枚举

#include<iostream>
#include<vector>
#include<cstring>
#include<algorithm>

using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
const int maxn=2e5+5;
const ll inf=0x3f3f3f3f3f3f3f3f;
ll a[maxn],prea[maxn],prea2[maxn],sufa[maxn],sufa2[maxn];
int main()
{
	ios::sync_with_stdio(false);
	ll n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	sort(a+1,a+n+1);
	ll minn=inf;
	for(ll i=a[1];i<=a[n];i++)
	{
		ll ans=0;
		for(int j=1;j<=n;j++)
		{
			if(a[j]<i)
				ans+=(i-a[j])*(i-a[j]);
			else if(a[j]>=i && a[j]<=i+m)
				continue;
			else
				ans+=(a[j]-(i+m))*(a[j]-(i+m));
		}
		minn=min(ans,minn);
	}
	cout<<minn<<endl;
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_40423146/article/details/88664568
今日推荐