我的退火怎么了,提交三页才5分
查看原帖
我的退火怎么了,提交三页才5分
52381
CodingJellyfish楼主2021/1/20 07:07
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef int I;
typedef char C;
typedef double F;

C _inbuf[10000001], _outbuf[10000001];
C *_in = _inbuf, *_out = _outbuf;

#define getC() *_in++
#define putC(c) *_out++ = c

I getI() {
	I ret = 0, fac = 1;
	C ch = getC();
	while(!isdigit(ch)) {
		if(ch == '-')
			fac = -1;
		ch = getC();
	}
	while(isdigit(ch)) {
		ret = ret * 10 + ch -'0';
		ch = getC();
	}
	return ret * fac;
}

void putI(I num) {
	static char buf[51], *p = buf;
	do {
		*++p = num % 10 + '0';
		num /= 10;
	}while(num);
	while(p != buf)
		putC(*p--);
}

#define N 301
I n, ans = 2147483647, vi[N];

I v() {
	I i, l = 0, r = 0;
	for(i = 1; i <= (n+1) / 2; i ++)
		l += vi[i];
	for(i = (n+1) / 2 + 1; i <= n; i ++)
		r += vi[i];
	return abs(l-r);                                                    
}

F START=5000;
F END=1e-10;
F DELTA=0.9112;
F TIME=1000;

#define swap(a,b) ({I tmp=a;a=b;b=tmp;})

void SA() {
	F i;
	for(i = START; i > END; i *= DELTA) {
        I i = rand() % n + 1, j = rand() % n + 1;
		swap(vi[i], vi[j]);
		I tmp = v();
		if(tmp < ans)
			ans = tmp;
		else if(exp((F)(ans-tmp) / i)<(F)rand()/(F)RAND_MAX)
			swap(vi[i],vi[j]);
	}
}

void solve() {
	I i;
	n = getI();
	for(i = 1; i <= n; i ++)
		vi[i] = getI();
	for(i = TIME; i; i--)
		SA();
	putI(ans);
	putC('\n');
	ans = 2147483647;
}
int main() {
    srand(rand());
	fread(_inbuf, sizeof(C), sizeof(_inbuf), stdin);
	I i = getI();
	while(i--)
		solve();
	fwrite(_outbuf, sizeof(C), _out-_outbuf, stdout);
	return 0;
}
2021/1/20 07:07
加载中...