后5个点AC,前5个点全WA,求调!
查看原帖
后5个点AC,前5个点全WA,求调!
206424
TyZErr233楼主2022/11/10 21:55

代码如下,其中的命名解释:

val: 每个数据的值
grp: 数据分到的组号
sum: 每个组的数据和
avg: sum 的平均数
ans: 答案
sig: 本次尝试的标准差
delta: sig - ans
sq(): 平方
getSig(): 获取当前标准差
#include <iostream>
#include <cmath>
#include <random>
constexpr double COOLDOWN(0.999), EPS(1e-15);
constexpr int MAXN(22);
using namespace std;
namespace Answer {
	int n, m, val[MAXN], grp[MAXN], sum[MAXN];
	double avg, ans;
	inline double sq(double x) { return x * x;	}
	double getSig() {
		double ret(0.0);
		for (int i(1); i <= m; ++ i)
			ret += sq(sum[i] - avg);
		return sqrt(ret / m);
	}
	void sa() {
		int x, y;
		double temp(100.0), nSig, delta;
		while (temp > EPS) {
			do {
				x = rand() % n + 1;
				y = rand() % n + 1;
			} while (x == y);
			sum[grp[x]] -= val[x] - val[y];
			sum[grp[y]] -= val[x] - val[y];
			delta = (nSig = getSig()) - ans;
			if (delta < 0 || exp(-delta / temp) * RAND_MAX > rand()) {
				grp[x] ^= grp[y] ^= grp[x] ^= grp[y];
				ans = nSig;
			} else {
				sum[grp[x]] += val[x] - val[y];
				sum[grp[y]] += val[x] - val[y];
			}
			temp *= COOLDOWN;
		}
		return;
	}
	void main() {
		scanf("%d%d", &n, &m);
		for (int i(1); i <= n; ++ i) {
			scanf("%d", val + i);
			avg += val[i];
			sum[grp[i] = i % m + 1] += val[i];
		}
		avg /= m;
		ans = getSig();
		sa();
		sa();
		sa();
		sa();
		sa();
		sa();
		sa();
		printf("%.2lf", ans);
		return;
	}
}
int main() {
	Answer::main();
	return 0;
} 
2022/11/10 21:55
加载中...