题解里的和我写的差不多的代码一遍过了,我不是很认可。
目前来看大多数题解里的参数我都试过了,没有用。
应该是单次退火复杂度太高导致次数不够。
或者是我没存最优解而被较劣解覆盖。
下面这份代码指令集都用了还是 74 pts。
另外求比较好的对题调参方法,bdfs 无果。
在线等,不急。
#include<bits/stdc++.h>
#pragma GCC target("avx")
using namespace std;
const int N=22;
const int dx[]={0,1,0,-1};
const int dy[]={1,0,-1,0};
int cnt,n,m,c,q[N<<3],a[N][N],vis[N][N];
bool valid(int x,int y) {return x>=1 && x<=n && y>=1 && y<=m;}
int f()
{
int cnt=0;
for(int x=1;x<=n;x++)
for(int y=1;y<=n;y++)
for(int i=0;i<4;i++)
{
int nx=x+dx[i],ny=y+dy[i];
if(valid(nx,ny) && a[x][y]!=a[nx][ny]) cnt++;
}
return cnt/2;
}
int ans;
int b[N][N];
void SA()
{
double T=10;
while(T>=1e-2)
{
int x_1,y_1,x_2,y_2;
do
{
x_1=rand()%n+1;
x_2=rand()%n+1;
y_1=rand()%m+1;
y_2=rand()%m+1;
}while(x_1==x_2 && y_1==y_2);
swap(a[x_1][y_1],a[x_2][y_2]);
int nowans=f();
int d=nowans-ans;
if(d<0)
{
ans=nowans;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
b[i][j]=a[i][j];
}
else if(exp(-d/T)*RAND_MAX>rand())
{
ans=nowans;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
b[i][j]=a[i][j];
}
else swap(a[x_1][y_1],a[x_2][y_2]);
T*=0.9998;
}
}
signed main()
{
srand(107.77777777);
srand(rand());
cin>>n>>m>>c;
for(int i=1;i<=c;i++) cin>>q[i];
int ptr=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
if(!q[ptr]) ptr++;
a[i][j]=ptr;q[ptr]--;
}
ans=f();
while((double)clock()/CLOCKS_PER_SEC<=4.87) SA();
for(int i=1;i<=n;i++,puts(""))
for(int j=1;j<=m;j++)
printf("%d ",b[i][j]);
return 0;
}
/*
*/