rt,分数稳定在 90pts ~ 99pts
就是上不到 100pts
是初解构造的太烂还是参数不行啊(
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <random>
using namespace std;
using pii = pair<int, int>;
random_device srd;
mt19937 gen(srd());
#define x first
#define y second
int const N = 25;
static const int dx[] = {1, -1, 0, 0};
static const int dy[] = {0, 0, 1, -1};
struct FSIO {
template<typename types>
FSIO operator >> (types &x) {
x = 0; bool neg = false; char ch = getchar();
while(!isdigit(ch)) {
if(ch == '-') neg = true;
ch = getchar();
}
while(isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
x = neg ? -x : x; return *this;
}
template<typename types>
FSIO operator << (types x) {
static char buf[130]; int tot = 0;
if(x < 0) putchar('-'), x = -x;
if(!x) putchar('0');
while(x) buf[tot] = x % 10 + '0', x /= 10, ++ tot;
while(tot) -- tot, putchar(buf[tot]);
return *this;
}
FSIO operator <<(bool x) {
putchar(x ? '1' : '0');
return *this;
}
FSIO operator << (char x) {
putchar(x);
return *this;
}
FSIO operator << (const char *x) {
int len = strlen(x);
for(int i = 0; i < len; ++ i) putchar(x[i]);
return *this;
}
} fio;
int n, m, c;
static int p[N];
int mp[N][N];
int cur; pii pcur;
inline int fstcalc() {
int res = 0;
for(int x = 1; x <= n; ++ x)
for(int y = 1; y <= m; ++ y)
for(int i = 0; i < 4; ++ i) {
int nx = x + dx[i], ny = y + dy[i];
if(nx > n || nx < 1 || ny > m || ny < 1) continue;
res += (mp[x][y] != mp[nx][ny]);
}
return (res / 2);
}
inline int calc(int x1, int y1, int x2, int y2) {
int res1 = 0;
for(int i = 0; i < 4; ++ i) {
int nx1 = x1 + dx[i], ny1 = y1 + dy[i], nx2 = x2 + dx[i], ny2 = y2 + dy[i];
if(1 <= nx1 && nx1 <= n && 1 <= ny1 && ny1 <= m) res1 += (mp[x1][y1] != mp[nx1][ny1]);
if(1 <= nx2 && nx2 <= n && 1 <= ny2 && ny2 <= m) res1 += (mp[x2][y2] != mp[nx2][ny2]);
}
swap(mp[x1][y1], mp[x2][y2]);
int res2 = 0;
for(int i = 0; i < 4; ++ i) {
int nx1 = x1 + dx[i], ny1 = y1 + dy[i], nx2 = x2 + dx[i], ny2 = y2 + dy[i];
if(1 <= nx1 && nx1 <= n && 1 <= ny1 && ny1 <= m) res2 += (mp[x1][y1] != mp[nx1][ny1]);
if(1 <= nx2 && nx2 <= n && 1 <= ny2 && ny2 <= m) res2 += (mp[x2][y2] != mp[nx2][ny2]);
}
swap(mp[x1][y1], mp[x2][y2]);
return res1 - res2;
}
inline pii lineToSq(int x) {
if(x % m == 0) return pii{x / m, m};
return pii{x / m + 1, x % m};
}
inline int sqToLine(pii t) {
return (t.x - 1) * m + t.y;
}
inline void sa() {
for(double tem = 1e14; tem > 5e-7; tem *= 0.99997) {
int t = gen() % (n * m) + 1;
pii pt = lineToSq(t), pcur = lineToSq(gen() % (n * m) + 1);
/*if(mp[pt.x][pt.y] == 0 || mp[pcur.x][pcur.y] == 0) {
cerr << pt.x << " " << pt.y << " " << pcur.x << " " << pcur.y << endl;
exit(-1);
}*/
int derta = calc(pcur.x, pcur.y, pt.x, pt.y); // derta < 0 worse, derta > 0, better
// if(derta == 1) cerr << (1.0 * derta / tem) << endl;
if(exp(1.0 * derta / tem) >= 1.0) {
// cerr << cur << " " << derta << endl;
cur -= derta, swap(mp[pcur.x][pcur.y], mp[pt.x][pt.y]);
}
}
}
inline void output() {
for(int i = 1; i <= n; ++ i) {
for(int j = 1; j <= m; ++ j)
fio << mp[i][j] << " ";
putchar('\n');
}
}
int main() {
srand(time(NULL));
fio >> n >> m >> c;
for(int i = 1; i <= c; ++ i) fio >> p[i];
int x = 0, y = 1;
//mp[1][1] = mp[1][2] = 1; mp[1][3] = mp[2][3] = 2; mp[2][1] = mp[3][1] = mp[2][2] = mp[3][3] = mp[3][2] = 3;
// output();
for(int i = 1; i <= n; ++ i) {
for(int j = 1; j <= m; ++ j) {
if(++ x > p[y]) x = 1, ++ y;
mp[i][j] = y;
}
}
//output();
//mp[1][1] = mp[2][1] = 2, mp[1][2] = mp[2][2] = mp[2][3] = 3, mp[1][3] = 1;
cur = fstcalc(), pcur = {1, 1};
while((double)clock() / CLOCKS_PER_SEC < 4.7) sa();
output();
//cerr << fstcalc() << endl;
return 0;
}