典中典之爬山过 NOIP T3
查看原帖
典中典之爬山过 NOIP T3
120911
Lynkcat楼主2021/11/30 19:57

拿考场代码改了改,原来我的爬山就是裸的爬山,在差分数组里随两个位置交换。

然后我先把差分数组排成单谷的,然后在两部分里分别随一个然后交换再排序,然后惊讶发现拿到了 96 的高分,多交了几发就 A 了。

///tui yi le. rp++
#include<bits/stdc++.h>
#define ll long long
#define pa pair<int,int>
#define se second
#define fi first
#define N 10005
//#define int ll
using namespace std;
ll read()
{
	ll x=0,fh=1;
	char ch=getchar();
	while (!isdigit(ch))
	{
		if (ch=='-') fh=-1;
		ch=getchar();
	}
	while (isdigit(ch))
	{
		x=(x*10+ch-'0');
		ch=getchar();
	}
	return fh*x;
}
void write(ll x)
{
	if (x<0)
	{
		putchar('-');
		write(-x);
		return;
	}
	if (x>=10) write(x/10);
	putchar((x%10)+'0');
}
void writeln(ll x)
{
	write(x);
	putchar('\n');
}
void writesp(ll x)
{
	write(x);
	putchar(' ');
}
int n,a[N],b[N];
int c[N];
int rnd(int l,int r)
{
	return rand()%(r-l+1)+l;
}
inline ll check()
{
	ll x=0,y=0;
	for (int i=1;i<=n;i++)
	{
		if (i>=2) a[i]=a[i-1]+b[i-1];
		x+=a[i]*a[i],y+=a[i];
	}
	return x*n-y*y;
}
signed main()
{
	
//	freopen("variance.in","r",stdin);
////	freopen("variance.out","w",stdout); 
	srand(time(0));
	n=read();
	for (int i=1;i<=n;i++)
	{
		a[i]=read();
	}
	for (int i=1;i<=n;i++)
	{
		b[i]=a[i+1]-a[i];
	}
	sort(b+1,b+n);
	int l=1,r=n-1,x=n-1;
	while (l<=r)
	{
		c[l++]=b[x--];
		if (l>r) break;
		c[r--]=b[x--];
	}
	for (int i=1;i<n;i++) b[i]=c[i];
	ll lstans=check();
	int B=500000;
	if (n>400) B=5000;
	if (n==20) B=5000000;
	for (int i=1;i<=B;i++)
	{
		int x=rnd(1,(n-1)/2),y=rnd((n-1)/2+1,n-1);
		swap(b[x],b[y]);
		for (int ii=1;ii<n;ii++) c[ii]=b[ii];
		sort(b+1,b+(n-1)/2+1,greater<int>());
		sort(b+(n-1)/2+1,b+n);
		if (check()>lstans) 
		{
			swap(c[x],c[y]);
			for (int ii=1;ii<n;ii++) b[ii]=c[ii];
		}
		else
		lstans=check();
	}
	writeln(lstans);
}

盲猜要被全机房再次追杀(wcr正在掐死我)

2021/11/30 19:57
加载中...