特别提醒!!!
查看原帖
特别提醒!!!
247842
zhenji_190127楼主2021/4/25 20:17

要是您是像我一样分的两组来做的

请一定要加上特判n==1的情况

不然会一直RE

只能过前面6个点

#include<bits/stdc++.h>
using namespace std;
int K;
int n;
const long double eps=1e-5;//注意调整
int lima;
int limb; 
long long coin[31];
long long a[31];
long long b[31];
long long bestx;
long long ansx;
long long f()
{
	long long suma=0;
	for(int i=1;i<=lima;i++)
		suma+=a[i];
	long long sumb=0;
	for(int i=1;i<=limb;i++)
		sumb+=b[i];
	if(suma<sumb)swap(suma,sumb);
	return suma-sumb;
}
void SA()
{
	long double T=8000;
	while(T>eps)
	{
		int p=rand()%lima+1;
		int q=rand()%limb+1;
		swap(a[p],b[q]);
		long double cx=f();
		long double delta=cx-ansx;
		if(delta<0)ansx=cx;//如果比之前还要优就直接接受这个新答案 
		else if(exp(-delta/T)*RAND_MAX>rand())ansx=cx;//没有之前优就有一定概率去接受 
		else swap(a[p],b[q]);//如果没有接受新的答案就交换回来 
		if(bestx>ansx)bestx=ansx;
		T*=0.998;
	}
}
int main()
{
//	srand(20190127);
	scanf("%d",&K);
	while(K--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%d",&coin[i]);
		if(n==1){//________________________如果没加这一句会一直RE___________________ 
			printf("%d\n",coin[1]);
			continue;
			}
		//sort(coin+1,coin+1+n);
		lima=limb=n/2;
		if(double(n)/2>n/2)lima+=1;
		//printf("a %d : ",lima);
		for(int i=1;(i-1)*2+1<=n;i++)
		{
			a[i]=coin[(i-1)*2+1];
		//	printf("%d ",(i-1)*2+1);
		}
		//printf("\n");
		//printf("b %d : ",limb);
		for(int i=1;i*2<=n;i++)
		{
			b[i]=coin[i*2];
		//	printf("%d ",i*2);
		}
		//printf("\n");
		bestx=ansx=f();
		int tim=9;
		while(tim--)
			SA();
		printf("%d\n",bestx);
	}
	return 0;
 } 
2021/4/25 20:17
加载中...