其他分享
首页 > 其他分享> > 2021 7.24 模拟测试 2.友好的序列

2021 7.24 模拟测试 2.友好的序列

作者:互联网

描述

在信息竞赛班的一次欢乐活动中,为了增强友谊,同学们站成了一列,编号从1到n。每个人 手上都有一个球,球上有一个数字。游戏规定对于任意两个人(i,j),他们的友好度为(i-j)2+g(i,j)2,其中g(i,j)= ∑ jk=i+1a[k]
请你帮助老师计算出任意两个人的最小可能友好度是多少?

输入

第一行1个整数 接下来一行是N个整数,表示每个人手上球上的数字。

输出

输出 1个整数表示最小的友好度

输入样例

4
1 0 0 -1

输出样例

1

【数据规模和约定】

40%的数据保证:
100%的数据保证:

题解

正解

设s[i]为前缀和,g(i,j)即为sum[j]-sum[i]
问题变为求平面内最近点对
1、选取一垂直线l:x=m 来作为分割直线。其中 为 中各点x坐标的中位数。由此将S分割为S1和S2。
2、递归地在S1和S2上找出其最小距离d1和d2,并设d=min{d1,d2},S中的最接近点对或者是d,或者是某个{p,q},其中p∈P1且q∈P2。最后枚举区间间点对。

非正解

这个竟然可以n2,加一步剪枝即可
枚举每个点,若当前(i-j)2>ans,由于(sum[i]-sum[j])2>0
则直接停止搜索

代码

非正解

#include<bits/stdc++.h>
using namespace std;
#define pf(x,y) (x-y)*(x-y)
#define int long long
#define in read()
inline int read()
{
    int data=0;int w=1; char ch=getchar();
    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0' && ch<='9') data=(data<<3)+(data<<1)+ch-'0',ch=getchar();
    return data*w;
}
int n,a[100005],sum[100005],ans=1e18;
int dist(int x,int y)
{
	int ret=pf(x,y);
	if(ret>ans) return -1;
	return ret;
}
signed main()
{
	n=in;
	for(int i=1;i<=n;i++) a[i]=in,sum[i]=sum[i-1]+a[i];
	for(int i=1;i<n;i++)
		for(int j=i+1;j<=n;j++)
		{
			int ret=dist(i,j);
			if(ret==-1) break;
			int g=pf(sum[i],sum[j]);
			ans=min(ans,g+ret);
		}
	cout<<ans;
}

正解

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define in read()
inline int read()
{
    int data=0;int w=1; char ch=getchar();
    while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar();
    if(ch=='-') w=-1,ch=getchar();
    while(ch>='0' && ch<='9') data=(data<<3)+(data<<1)+ch-'0',ch=getchar();
    return data*w;
}
const int N=1e5+10;
int q[N],k;
struct node{int x;ll y;}p[N];
bool cmp1(node a,node b){return a.x<b.x;}
bool cmp2(node a,node b){return a.y<b.y;}
ll dis2(int a,int b){return (ll)(p[a].x-p[b].x)*(p[a].x-p[b].x)+(ll)(p[a].y-p[b].y)*(p[a].y-p[b].y);}
ll solve(int l,int r)
{
	if(l==r)return 1e18;
	int mid=l+r>>1;
	ll d2=min(solve(l,mid),solve(mid+1,r));
	inplace_merge(&p[l],&p[mid+1],&p[r+1],cmp2);
	k=0;
	double d=sqrt(d2);
	for(int i=l;i<=r;++i)
		if(fabs(p[mid].x-p[i].x)<d)
			q[++k]=i;
	for(int i=1;i<=k;++i)
		for(int j=i+1;j<=k&&p[q[j]].y-p[q[i]].y<d;++j)
			d2=min(d2,dis2(q[i],q[j]));
	return d2;
}
signed main()
{
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
	n=in;
	for(int i=1,w;i<=n;++i)
	{
		a[i]=in,sum[i]=sum[i-1]+a[i];
		p[i].x=i,p[i].y=p[i-1].y+a[i];
	}
		sort(p+1,p+n+1,cmp1);
		cout<<solve(1,n);
	return 0;
}

标签:ch,int,7.24,read,2021,序列,define,d2,getchar
来源: https://www.cnblogs.com/Socratize/p/15055374.html