Topcoder Marathon Match 96 最終結果
作成日:2018.01.10
カテゴリー:競プロ 参戦記録
目次
最終結果
$967547.39$点で順位はシステムテスト前と変わらず$8$位。
解法
2つの敷き詰め方を試して良かった方を採用する。
敷き詰め方はいずれもまずは周囲を埋め、中央に残った空きマスに対して伸ばせるところを伸ばす山登り(solve1)を行う。
山登りを行う際に、伸ばせる時にも$3/4$の確率で伸ばさないようにする。
このことによってランダム性が生じるので、山登りパートを時間いっぱい(それぞれ$4.99$sec)何度も繰り返し行い最も良かったものを答えとする。
敷き詰め方のうちの一方(solveA)では、右辺と上辺を直線のワイヤでまっすぐに、左辺と下辺を曲がったワイヤでジグザグに埋めれる限り埋める。
もう一方(solveB)では、まず曲がったワイヤでジグザグに四辺を埋めれる限り埋めていく。
そして、まだ埋めていないマスを端から直線のワイヤを用いて伸ばすことで埋めていく。
ソースコード
#include <bits/stdc++.h>
#include <sys/time.h>
using namespace std;
typedef long long LL;
#define repp(i,a,b) for(int i = (int)(a) ; i < (int)(b) ; ++i)
#define repm(i,a,b) for(int i = (int)(a) ; i > (int)(b) ; --i)
const double MAX_TIME = 4.99;
double get_time() {
timeval tv;
gettimeofday(&tv, NULL);
return tv.tv_sec + 1e-6 * tv.tv_usec;
}
unsigned int xor128(){
static unsigned int x=987654301,y=362436069,z=521288629,w=88675123;
unsigned int t = (x^(x<<11));
x=y;y=z;z=w;
return w=(w^(w>>19))^(t^(t>>8));
}
bool rnd_accept(){
return !(xor128()&3);
}
const int MC = 102;
const int NT = 24;
class GarlandOfLights {
const int dx[4] = {0,1,0,-1};
const int dy[4] = {1,0,-1,0};
const int lg[16] = {-1,0,1,-1,2,-1,-1,-1,3,-1,-1,-1,-1,-1,-1,-1};
const int code[8] = {3,6,12,9,5,10,0,0};
const int decode[16] = {-1,-1,-1,0,-1,4,1,-1,-1,3,5,-1,2,-1,-1,-1};
vector<int> tile[NT];
int tile_count[NT];
int ini_tile_count[NT];
int best_tile_count[NT];
int wire_count[8];
char ans[MC][MC];
char best[MC][MC];
int bestscore,nowscore;
char ini[MC][MC];
int H,W;
int h_min , h_max , w_min , w_max;
int color_num;
bool horizontal(int now_x , int now_y){ //横線から縦方向に伸ばす
int w0 = code[ans[now_x][now_y]>>2]^1;
int w3 = code[ans[now_x][now_y+1]>>2]^4;
int c0 = ans[now_x+dx[lg[w0]]][now_y+dy[lg[w0]]]&3;
int c3 = ans[now_x+dx[lg[w3]]][now_y+1+dy[lg[w3]]]&3;
++tile_count[ans[now_x][now_y]];
++tile_count[ans[now_x][now_y+1]];
if((!~ans[now_x+1][now_y]) && (!~ans[now_x+1][now_y+1])){
int k1 = xor128()%color_num , k2 = xor128()%(color_num-1);
if(k2 >= k1) ++k2;
if(tile_count[12|k1] && tile_count[8|k2]){
int k0 = -1 , k3 = -1;
int r0 = decode[2|w0]<<2 , r3 = decode[2|w3]<<2;
repp(t,0,color_num) if(t != c0 && t != k1){
if((k0<0 && tile_count[r0|t]) || (k0>=0 && tile_count[r0|k0] < tile_count[r0|t])) k0 = t;
}
repp(t,0,color_num) if(t != c3 && t != k2){
if((k3<0 && tile_count[r3|t]+((r3|t)==(r0|k0)?-1:0)) || (k3>=0 && tile_count[r3|k3] < tile_count[r3|t]+((r3|t)==(r0|k0)?-1:0))) k3 = t;
}
if((~k0) && (~k3) && rnd_accept()){
--tile_count[r0|k0];
--tile_count[12|k1];
--tile_count[8|k2];
--tile_count[r3|k3];
ans[now_x][now_y] = (r0|k0);
ans[now_x+1][now_y] = (12|k1);
ans[now_x+1][now_y+1] = (8|k2);
ans[now_x][now_y+1] = (r3|k3);
--nowscore;
return 1;
}
}
}
if((!~ans[now_x-1][now_y]) && (!~ans[now_x-1][now_y+1])){
int k1 = xor128()%color_num , k2 = xor128()%(color_num-1);
if(k2 >= k1) ++k2;
if(tile_count[k1] && tile_count[4|k2]){
int k0 = -1 , k3 = -1;
int r0 = decode[8|w0]<<2 , r3 = decode[8|w3]<<2;
repp(t,0,color_num) if(t != c0 && t != k1){
if((k0<0 && tile_count[r0|t]) || (k0>=0 && tile_count[r0|k0] < tile_count[r0|t])) k0 = t;
}
repp(t,0,color_num) if(t != c3 && t != k2){
if((k3<0 && tile_count[r3|t]+((r3|t)==(r0|k0)?-1:0)) || (k3>=0 && tile_count[r3|k3] < tile_count[r3|t]+((r3|t)==(r0|k0)?-1:0))) k3 = t;
}
if((~k0) && (~k3) && rnd_accept()){
--tile_count[r0|k0];
--tile_count[k1];
--tile_count[4|k2];
--tile_count[r3|k3];
ans[now_x][now_y] = (r0|k0);
ans[now_x-1][now_y] = k1;
ans[now_x-1][now_y+1] = (4|k2);
ans[now_x][now_y+1] = (r3|k3);
--nowscore;
return 1;
}
}
}
--tile_count[ans[now_x][now_y]];
--tile_count[ans[now_x][now_y+1]];
return 0;
}
bool vertical(int now_x , int now_y){ //縦線から横方向に伸ばす
int w0 = code[ans[now_x][now_y]>>2]^2;
int w3 = code[ans[now_x+1][now_y]>>2]^8;
int c0 = ans[now_x+dx[lg[w0]]][now_y+dy[lg[w0]]]&3;
int c3 = ans[now_x+1+dx[lg[w3]]][now_y+dy[lg[w3]]]&3;
++tile_count[ans[now_x][now_y]];
++tile_count[ans[now_x+1][now_y]];
if((!~ans[now_x][now_y+1]) && (!~ans[now_x+1][now_y+1])){
int k1 = xor128()%color_num , k2 = xor128()%(color_num-1);
if(k2 >= k1) ++k2;
if(tile_count[4|k1] && tile_count[8|k2]){
int k0 = -1 , k3 = -1;
int r0 = decode[1|w0]<<2 , r3 = decode[1|w3]<<2;
repp(t,0,color_num) if(t != c0 && t != k1){
if((k0<0 && tile_count[r0|t]) || (k0>=0 && tile_count[r0|k0] < tile_count[r0|t])) k0 = t;
}
repp(t,0,color_num) if(t != c3 && t != k2){
if((k3<0 && tile_count[r3|t]+((r3|t)==(r0|k0)?-1:0)) || (k3>=0 && tile_count[r3|k3] < tile_count[r3|t]+((r3|t)==(r0|k0)?-1:0))) k3 = t;
}
if((~k0) && (~k3) && rnd_accept()){
--tile_count[r0|k0];
--tile_count[4|k1];
--tile_count[8|k2];
--tile_count[r3|k3];
ans[now_x][now_y] = (r0|k0);
ans[now_x][now_y+1] = (4|k1);
ans[now_x+1][now_y+1] = (8|k2);
ans[now_x+1][now_y] = (r3|k3);
--nowscore;
return 1;
}
}
}
if((!~ans[now_x][now_y-1]) && (!~ans[now_x+1][now_y-1])){
int k1 = xor128()%color_num , k2 = xor128()%(color_num-1);
if(k2 >= k1) ++k2;
if(tile_count[k1] && tile_count[12|k2]){
int k0 = -1 , k3 = -1;
int r0 = decode[4|w0]<<2 , r3 = decode[4|w3]<<2;
repp(t,0,color_num) if(t != c0 && t != k1){
if((k0<0 && tile_count[r0|t]) || (k0>=0 && tile_count[r0|k0] < tile_count[r0|t])) k0 = t;
}
repp(t,0,color_num) if(t != c3 && t != k2){
if((k3<0 && tile_count[r3|t]+((r3|t)==(r0|k0)?-1:0)) || (k3>=0 && tile_count[r3|k3] < tile_count[r3|t]+((r3|t)==(r0|k0)?-1:0))) k3 = t;
}
if((~k0) && (~k3) && rnd_accept()){
--tile_count[r0|k0];
--tile_count[k1];
--tile_count[12|k2];
--tile_count[r3|k3];
ans[now_x][now_y] = (r0|k0);
ans[now_x][now_y-1] = k1;
ans[now_x+1][now_y-1] = (12|k2);
ans[now_x+1][now_y] = (r3|k3);
--nowscore;
return 1;
}
}
}
--tile_count[ans[now_x][now_y]];
--tile_count[ans[now_x+1][now_y]];
return 0;
}
void solve0(){ //右下に最小の四角を構成
int now_x = H-1 , now_y = W-1;
int z0 = -1 , z1 = -1 , z2 = -1 , z3 = -1;
repp(i,0,4) if((z0<0 && tile_count[i]) || (z0>=0 && tile_count[z0] < tile_count[i])) z0 = i;
ans[now_x][now_y] = z0;
if(~z0) --tile_count[z0];
repp(i,0,4) if(i != z0 && ((z1<0 && tile_count[4|i]) || (z1>=0 && tile_count[4|z1] < tile_count[4|i]))) z1 = i;
ans[now_x][now_y+1] = (4|z1);
if(~z1) --tile_count[4|z1];
repp(i,0,4) if(i != z0 && ((z3<0 && tile_count[12|i]) || (z3>=0 && tile_count[12|z3] < tile_count[12|i]))) z3 = i;
ans[now_x+1][now_y] = (12|z3);
if(~z3) --tile_count[12|z3];
repp(i,0,4) if(i != z1 && i != z3 && ((z2<0 && tile_count[8|i]) || (z2>=0 && tile_count[8|z2] < tile_count[8|i]))) z2 = i;
ans[now_x+1][now_y+1] = (8|z2);
if(~z2) --tile_count[8|z2];
}
bool solve0_2(){
if(h_max-h_min<2 || w_max-w_min<4) return 0;
repm(i,h_max-1,h_min){
repp(t,20,24) if((ans[i+1][w_max]&3) != (t&3) && ((ans[i][w_max]<0 && tile_count[t]) || (ans[i][w_max]>=0 && tile_count[ans[i][w_max]] < tile_count[t]))) ans[i][w_max] = t;
if(!~ans[i][w_max]) return 0;
--tile_count[ans[i][w_max]];
}
repp(t,4,8) if((ans[h_min+1][w_max]&3) != (t&3) && ((ans[h_min][w_max]<0 && tile_count[t]) || (ans[h_min][w_max]>=0 && tile_count[ans[h_min][w_max]] < tile_count[t]))) ans[h_min][w_max] = t;
if(!~ans[h_min][w_max]) return 0;
--tile_count[ans[h_min][w_max]];
repm(j,w_max-1,w_min){
repp(t,16,20) if((ans[h_min][j+1]&3) != (t&3) && ((ans[h_min][j]<0 && tile_count[t]) || (ans[h_min][j]>=0 && tile_count[ans[h_min][j]] < tile_count[t]))) ans[h_min][j] = t;
if(!~ans[h_min][j]) return 0;
--tile_count[ans[h_min][j]];
}
repp(t,0,4) if((ans[h_min][w_min+1]&3) != (t&3) && ((ans[h_min][w_min]<0 && tile_count[t]) || (ans[h_min][w_min]>=0 && tile_count[ans[h_min][w_min]] < tile_count[t]))) ans[h_min][w_min] = t;
if(!~ans[h_min][w_min]) return 0;
--tile_count[ans[h_min][w_min]];
{
int i = h_min+1;
int j = w_min+2;
while(i<h_max-1){
repp(t,12,16) if((ans[i-1][w_min]&3) != (t&3) && ((ans[i][w_min]<0 && tile_count[t]) || (ans[i][w_min]>=0 && tile_count[ans[i][w_min]] < tile_count[t]))) ans[i][w_min] = t;
if(!~ans[i][w_min]) return 0;
--tile_count[ans[i][w_min]];
repp(t,4,8) if((ans[i][w_min]&3) != (t&3) && ((ans[i][w_min+1]<0 && tile_count[t]) || (ans[i][w_min+1]>=0 && tile_count[ans[i][w_min+1]] < tile_count[t]))) ans[i][w_min+1] = t;
if(!~ans[i][w_min+1]) return 0;
--tile_count[ans[i][w_min+1]];
++i;
repp(t,8,12) if((ans[i-1][w_min+1]&3) != (t&3) && ((ans[i][w_min+1]<0 && tile_count[t]) || (ans[i][w_min+1]>=0 && tile_count[ans[i][w_min+1]] < tile_count[t]))) ans[i][w_min+1] = t;
if(!~ans[i][w_min+1]) return 0;
--tile_count[ans[i][w_min+1]];
repp(t,0,4) if((ans[i][w_min+1]&3) != (t&3) && ((ans[i][w_min]<0 && tile_count[t]) || (ans[i][w_min]>=0 && tile_count[ans[i][w_min]] < tile_count[t]))) ans[i][w_min] = t;
if(!~ans[i][w_min]) return 0;
--tile_count[ans[i][w_min]];
++i;
}
if(i == h_max){
repp(t,12,16) if((ans[i-1][w_min]&3) != (t&3) && ((ans[i][w_min]<0 && tile_count[t]) || (ans[i][w_min]>=0 && tile_count[ans[i][w_min]] < tile_count[t]))) ans[i][w_min] = t;
if(!~ans[i][w_min]) return 0;
--tile_count[ans[i][w_min]];
repp(t,16,20) if((ans[i][w_min]&3) != (t&3) && ((ans[i][w_min+1]<0 && tile_count[t]) || (ans[i][w_min+1]>=0 && tile_count[ans[i][w_min+1]] < tile_count[t]))) ans[i][w_min+1] = t;
if(!~ans[i][w_min+1]) return 0;
--tile_count[ans[i][w_min+1]];
} else {
repp(t,20,24) if((ans[i-1][w_min]&3) != (t&3) && ((ans[i][w_min]<0 && tile_count[t]) || (ans[i][w_min]>=0 && tile_count[ans[i][w_min]] < tile_count[t]))) ans[i][w_min] = t;
if(!~ans[i][w_min]) return 0;
--tile_count[ans[i][w_min]];
++i;
repp(t,12,16) if((ans[i-1][w_min]&3) != (t&3) && ((ans[i][w_min]<0 && tile_count[t]) || (ans[i][w_min+1]>=0 && tile_count[ans[i][w_min]] < tile_count[t]))) ans[i][w_min] = t;
if(!~ans[i][w_min]) return 0;
--tile_count[ans[i][w_min]];
--j;
}
while(j<w_max-3){
repp(t,8,12) if((ans[h_max][j-1]&3) != (t&3) && ((ans[h_max][j]<0 && tile_count[t]) || (ans[h_max][j]>=0 && tile_count[ans[h_max][j]] < tile_count[t]))) ans[h_max][j] = t;
if(!~ans[h_max][j]) return 0;
--tile_count[ans[h_max][j]];
repp(t,0,4) if((ans[h_max][j]&3) != (t&3) && ((ans[h_max-1][j]<0 && tile_count[t]) || (ans[h_max-1][j]>=0 && tile_count[ans[h_max-1][j]] < tile_count[t]))) ans[h_max-1][j] = t;
if(!~ans[h_max-1][j]) return 0;
--tile_count[ans[h_max-1][j]];
++j;
repp(t,4,8) if((ans[h_max-1][j-1]&3) != (t&3) && ((ans[h_max-1][j]<0 && tile_count[t]) || (ans[h_max-1][j]>=0 && tile_count[ans[h_max-1][j]] < tile_count[t]))) ans[h_max-1][j] = t;
if(!~ans[h_max-1][j]) return 0;
--tile_count[ans[h_max-1][j]];
repp(t,12,16) if((ans[h_max-1][j]&3) != (t&3) && ((ans[h_max][j]<0 && tile_count[t]) || (ans[h_max][j]>=0 && tile_count[ans[h_max][j]] < tile_count[t]))) ans[h_max][j] = t;
if(!~ans[h_max][j]) return 0;
--tile_count[ans[h_max][j]];
++j;
}
if(j==w_max-3){
repp(t,16,20) if((ans[h_max][j-1]&3) != (t&3) && ((ans[h_max][j]<0 && tile_count[t]) || (ans[h_max][j]>=0 && tile_count[ans[h_max][j]] < tile_count[t]))) ans[h_max][j] = t;
if(!~ans[h_max][j]) return 0;
--tile_count[ans[h_max][j]];
++j;
}
repp(t,8,12) if((ans[h_max][j-1]&3) != (t&3) && ((ans[h_max][j]<0 && tile_count[t]) || (ans[h_max][j]>=0 && tile_count[ans[h_max][j]] < tile_count[t]))) ans[h_max][j] = t;
if(!~ans[h_max][j]) return 0;
--tile_count[ans[h_max][j]];
}
repp(t0,0,4) if((ans[h_max][w_max-2]&3) != t0 && tile_count[t0]){
repp(t1,0,4) if((ans[h_max][w_max-1]&3) != t1 && t0 != t1 && tile_count[4|t1]){
ans[h_max-1][w_max-2] = t0;
ans[h_max-1][w_max-1] = (4|t1);
--tile_count[t0];
--tile_count[4|t1];
return 1;
}
}
return 0;
}
bool solve3(){
if(h_max-h_min<4 || w_max-w_min<4) return 0;
int x = h_max - 1 , y = w_max;
while(x > h_min+1){
repp(t,4,8) if((ans[x+1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
repp(t,12,16) if((ans[x][y]&3) != (t&3) && ((ans[x][y-1]<0 && tile_count[t]) || (ans[x][y-1]>=0 && tile_count[ans[x][y-1]] < tile_count[t]))) ans[x][y-1] = t;
if(!~ans[x][y-1]) return 0;
--tile_count[ans[x][y-1]];
--x;
repp(t,0,4) if((ans[x+1][y-1]&3) != (t&3) && ((ans[x][y-1]<0 && tile_count[t]) || (ans[x][y-1]>=0 && tile_count[ans[x][y-1]] < tile_count[t]))) ans[x][y-1] = t;
if(!~ans[x][y-1]) return 0;
--tile_count[ans[x][y-1]];
repp(t,8,12) if((ans[x][y-1]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
--x;
}
if(x == h_min){
repp(t,4,8) if((ans[x+1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
--y;
repp(t,16,20) if((ans[x][y+1]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
--y;
} else {
repp(t,20,24) if((ans[x+1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
--x;
repp(t,4,8) if((ans[x+1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
--y;
}
while(y > w_min+1){
repp(t,0,4) if((ans[x][y+1]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
repp(t,8,12) if((ans[x][y]&3) != (t&3) && ((ans[x+1][y]<0 && tile_count[t]) || (ans[x+1][y]>=0 && tile_count[ans[x+1][y]] < tile_count[t]))) ans[x+1][y] = t;
if(!~ans[x+1][y]) return 0;
--tile_count[ans[x+1][y]];
--y;
repp(t,12,16) if((ans[x+1][y+1]&3) != (t&3) && ((ans[x+1][y]<0 && tile_count[t]) || (ans[x+1][y]>=0 && tile_count[ans[x+1][y]] < tile_count[t]))) ans[x+1][y] = t;
if(!~ans[x+1][y]) return 0;
--tile_count[ans[x+1][y]];
repp(t,4,8) if((ans[x+1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
--y;
}
if(y == w_min){
repp(t,0,4) if((ans[x][y+1]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
++x;
repp(t,20,24) if((ans[x-1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
++x;
} else {
repp(t,16,20) if((ans[x][y+1]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
--y;
repp(t,0,4) if((ans[x][y+1]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
++x;
}
while(x < h_max-1){
repp(t,12,16) if((ans[x-1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
repp(t,4,8) if((ans[x][y]&3) != (t&3) && ((ans[x][y+1]<0 && tile_count[t]) || (ans[x][y+1]>=0 && tile_count[ans[x][y+1]] < tile_count[t]))) ans[x][y+1] = t;
if(!~ans[x][y+1]) return 0;
--tile_count[ans[x][y+1]];
++x;
repp(t,8,12) if((ans[x-1][y+1]&3) != (t&3) && ((ans[x][y+1]<0 && tile_count[t]) || (ans[x][y+1]>=0 && tile_count[ans[x][y+1]] < tile_count[t]))) ans[x][y+1] = t;
if(!~ans[x][y+1]) return 0;
--tile_count[ans[x][y+1]];
repp(t,0,4) if((ans[x][y+1]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
++x;
}
if(x == h_max){
repp(t,12,16) if((ans[x-1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
++y;
repp(t,16,20) if((ans[x][y-1]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
++y;
} else {
repp(t,20,24) if((ans[x-1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
++x;
repp(t,12,16) if((ans[x-1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
++y;
}
while(y < w_max - 1){
repp(t,8,12) if((ans[x][y-1]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
repp(t,0,4) if((ans[x][y]&3) != (t&3) && ((ans[x-1][y]<0 && tile_count[t]) || (ans[x-1][y]>=0 && tile_count[ans[x-1][y]] < tile_count[t]))) ans[x-1][y] = t;
if(!~ans[x-1][y]) return 0;
--tile_count[ans[x-1][y]];
++y;
repp(t,4,8) if((ans[x-1][y-1]&3) != (t&3) && ((ans[x-1][y]<0 && tile_count[t]) || (ans[x-1][y]>=0 && tile_count[ans[x-1][y]] < tile_count[t]))) ans[x-1][y] = t;
if(!~ans[x-1][y]) return 0;
--tile_count[ans[x-1][y]];
repp(t,12,16) if((ans[x-1][y]&3) != (t&3) && ((ans[x][y]<0 && tile_count[t]) || (ans[x][y]>=0 && tile_count[ans[x][y]] < tile_count[t]))) ans[x][y] = t;
if(!~ans[x][y]) return 0;
--tile_count[ans[x][y]];
++y;
}
return 1;
}
bool solve4_h(){
{
int c0 = -1 , c1 = -1;
repp(t,20,24) if((ans[h_max+2][w_max-1]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) return 0;
++tile_count[ans[h_max+1][w_max-1]];
ans[h_max+1][w_max-1] = c0;
--tile_count[c0];
repp(t,20,24) if((ans[h_max+2][w_max]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) return 0;
++tile_count[ans[h_max+1][w_max]];
ans[h_max+1][w_max] = c1;
--tile_count[c1];
}
repm(i,h_max,h_min){
int c0 = -1 , c1 = -1;
repp(t,20,24) if((ans[i+1][w_max-1]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) return 0;
ans[i][w_max-1] = c0;
--tile_count[c0];
repp(t,20,24) if((ans[i+1][w_max]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) return 0;
ans[i][w_max] = c1;
--tile_count[c1];
}
{
int c0 = -1 , c1 = -1;
repp(t,0,4) if((ans[h_min+1][w_max-1]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) return 0;
ans[h_min][w_max-1] = c0;
--tile_count[c0];
repp(t,4,8) if((ans[h_min+1][w_max]&3) != (t&3) && (c0&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) return 0;
ans[h_min][w_max] = c1;
--tile_count[c1];
}
w_max -= 2;
return 1;
}
bool solve4_w(){
{
int c0 = -1 , c1 = -1;
repp(t,16,20) if((ans[h_min][w_min-2]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) return 0;
++tile_count[ans[h_min][w_min-1]];
ans[h_min][w_min-1] = c0;
--tile_count[c0];
repp(t,16,20) if((ans[h_min+1][w_min-2]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) return 0;
++tile_count[ans[h_min+1][w_min-1]];
ans[h_min+1][w_min-1] = c1;
--tile_count[c1];
}
repp(j,w_min,w_max){
int c0 = -1 , c1 = -1;
repp(t,16,20) if((ans[h_min][j-1]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) return 0;
ans[h_min][j] = c0;
--tile_count[c0];
repp(t,16,20) if((ans[h_min+1][j-1]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) return 0;
ans[h_min+1][j] = c1;
--tile_count[c1];
}
{
int c0 = -1 , c1 = -1;
repp(t,4,8) if((ans[h_min][w_max-1]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) return 0;
ans[h_min][w_max] = c0;
--tile_count[c0];
repp(t,8,12) if((ans[h_min+1][w_max-1]&3) != (t&3) && (c0&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) return 0;
ans[h_min+1][w_max] = c1;
--tile_count[c1];
}
h_min += 2;
return 1;
}
void solveA(){
double end_time = get_time() + MAX_TIME;
solve0();
for(int i = 0 ; ; ++i){
memcpy(ini,ans,MC*MC);
memcpy(ini_tile_count,tile_count,NT*4);
if(i){
int c0 = -1 , c1 = -1 , c2 = -1 , c3 = -1;
repp(t0,20,24) if((ans[H+2-i*2][W-i-1]&3) != (t0&3) && ((c0<0 && tile_count[t0]) || (c0>=0 && tile_count[c0] < tile_count[t0]))) c0 = t0;
repp(t1,20,24) if((ans[H+2-i*2][W-i]&3) != (t1&3) && ((c1<0 && tile_count[t1]+(c0==t1?-1:0)) || (c1>=0 && tile_count[c1] < tile_count[t1]+(c0==t1?-1:0)))) c1 = t1;
repp(t2,20,24) if((c0&3) != (t2&3) && ((c2<0 && tile_count[t2]+(c0==t2?-1:0)+(c1==t2?-1:0)) || (c2>=0 && tile_count[c2] < tile_count[t2]+(c0==t2?-1:0)+(c1==t2?-1:0)))) c2 = t2;
repp(t3,20,24) if((c1&3) != (t3&3) && ((c3<0 && tile_count[t3]+(c0==t3?-1:0)+(c1==t3?-1:0)+(c2==t3?-1:0)) || (c3>=0 && tile_count[c3] < tile_count[t3]+(c0==t3?-1:0)+(c1==t3?-1:0)+(c2==t3?-1:0)))) c3 = t3;
if((~c0) && (~c1) && (~c2) && (~c3)){
++tile_count[ans[H+1-i*2][W-i-1]];
++tile_count[ans[H+1-i*2][W-i]];
ans[H+1-i*2][W-i-1] = c0;
ans[H+1-i*2][W-i] = c1;
ans[H-i*2][W-i-1] = c2;
ans[H-i*2][W-i] = c3;
--tile_count[c0];
--tile_count[c1];
--tile_count[c2];
--tile_count[c3];
} else {
break;
}
} else {
++tile_count[ans[H-1][W]];
++tile_count[ans[H-1][W-1]];
ans[H-1][W] = -1;
ans[H-1][W-1] = -1;
}
h_min = 1+i; h_max = H-i*2;
w_min = 1+i*2; w_max = W-i;
if(!solve0_2()) break;
}
h_min = max(1,h_min-1); h_max = min(H,h_max+1);
w_min = max(1,w_min-1); w_max = min(W,w_max+1);
memcpy(ans,ini,MC*MC);
memcpy(tile_count,ini_tile_count,NT*4);
int iniscore = 0;
repp(i,0,NT) iniscore += tile_count[i];
iniscore /= 2;
while(get_time() < end_time){
nowscore = iniscore;
solve1();
if(bestscore > nowscore){
memcpy(best,ans,MC*MC);
bestscore = nowscore;
}
memcpy(tile_count,ini_tile_count,NT*4);
memcpy(ans,ini,MC*MC);
}
}
void solveB(){
double end_time = get_time() + MAX_TIME;
for(int i = 0 ; ; ++i){
if(i){
int c0 = -1;
repp(t,20,24) if((ans[h_max+2][w_max]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) break;
++tile_count[ans[h_max+1][w_max]];
ans[h_max+1][w_max] = c0;
--tile_count[c0];
int c1 = -1;
repp(t,20,24) if((ans[h_max+2][w_max-1]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) break;
++tile_count[ans[h_max+1][w_max-1]];
ans[h_max+1][w_max-1] = c1;
--tile_count[c1];
int c2 = -1;
repp(t,20,24) if((ans[h_max+1][w_max]&3) != (t&3) && ((c2<0 && tile_count[t]) || (c2>=0 && tile_count[c1] < tile_count[t]))) c2 = t;
if(!~c2) break;
ans[h_max][w_max] = c2;
--tile_count[c2];
} else {
repp(t,8,12) if((ans[H][W]<0 && tile_count[t]) || (ans[H][W]>=0 && tile_count[ans[H][W]] < tile_count[t])) ans[H][W] = t;
--tile_count[ans[H][W]];
}
if(solve3()){
if(i){
int c0 = -1;
repp(t,4,8) if((ans[h_max][w_max-2]&3) != (t&3) && (ans[h_max+1][w_max-1]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) break;
ans[h_max][w_max-1] = c0;
--tile_count[c0];
} else {
int c0 = -1;
repp(t,16,20) if((ans[h_max][w_max-2]&3) != (t&3) && (ans[h_max][w_max]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) break;
ans[h_max][w_max-1] = c0;
--tile_count[c0];
}
} else {
if(!i){
repp(i,0,NT) tile_count[i] = tile[i].size();
repp(i,1,H+1) fill(ans[i]+1,ans[i]+W+1,-1);
solve0();
memcpy(ini,ans,MC*MC);
memcpy(ini_tile_count,tile_count,NT*4);
}
break;
}
memcpy(ini,ans,MC*MC);
memcpy(ini_tile_count,tile_count,NT*4);
h_min += 2; h_max -= 2;
w_min += 2; w_max -= 2;
}
memcpy(ans,ini,MC*MC);
memcpy(tile_count,ini_tile_count,NT*4);
if(~ans[1][1]){
bool b = 1;
if((h_max-h_min)%2==0 && (w_max-w_min)%2==0){
repp(i,4,6){
int z = tile_count[i<<2];
wire_count[i] = z;
repp(j,1,4){
wire_count[i] += tile_count[(i<<2)|j];
z = max(z,tile_count[(i<<2)|j]);
}
wire_count[i] = min(wire_count[i],(wire_count[i]-z)*2) - 4;
}
int dh = h_max - h_min + 1 , dw = w_max - w_min + 1;
int x = 0 , y = 0 , z = max(dh,dw);
for(int i = 2 ; i < dh ; i += 2){
if(dh-2*i<0) break;
int p = dw - wire_count[4] / (2*i) + 1;
int q = wire_count[5] / (2*(dh-i)) + 1;
repp(j,p,q){
if(dw-2*j<0) break;
if(j<0) j = -1;
if(j&1) continue;
if(z > max(abs(dh-2*i),abs(dw-2*j))){
x = i;
y = j;
z = max(abs(dh-2*i),abs(dw-2*j));
}
}
}
for(int j = 0 ; j < y ; j += 2){
++tile_count[ans[h_min-1][w_min+j]];
++tile_count[ans[h_min-1][w_min+j+1]];
++tile_count[ans[h_max+1][w_max-j]];
++tile_count[ans[h_max+1][w_max-j-1]];
bool b = 1;
repp(i,0,dh-x){
int c0 = -1 , c1 = -1;
repp(t,20,24) if((ans[h_min+i-2][w_min+j]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0){ b = 0; break;}
ans[h_min+i-1][w_min+j] = c0;
--tile_count[c0];
repp(t,20,24) if((ans[h_min+i-2][w_min+j+1]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1){ b = 0; break;}
ans[h_min+i-1][w_min+j+1] = c1;
--tile_count[c1];
c0 = -1; c1 = -1;
repp(t,20,24) if((ans[h_max-i+2][w_max-j]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0){ b = 0; break;}
ans[h_max-i+1][w_max-j] = c0;
--tile_count[c0];
repp(t,20,24) if((ans[h_max-i+2][w_max-j-1]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1){ b = 0; break;}
ans[h_max-i+1][w_max-j-1] = c1;
--tile_count[c1];
}
if(!b) break;
int c0 = -1 , c1 = -1;
repp(t,12,16) if((ans[h_max-x-1][w_min+j]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) break;
ans[h_max-x][w_min+j] = c0;
--tile_count[c0];
repp(t,8,12) if((ans[h_max-x-1][w_min+j+1]&3) != (t&3) && (c0&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) break;
ans[h_max-x][w_min+j+1] = c1;
--tile_count[c1];
c0 = -1; c1 = -1;
repp(t,4,8) if((ans[h_min+x+1][w_max-j]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) break;
ans[h_min+x][w_max-j] = c0;
--tile_count[c0];
repp(t,0,4) if((ans[h_min+x+1][w_max-j-1]&3) != (t&3) && (c0&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) break;
ans[h_min+x][w_max-j-1] = c1;
--tile_count[c1];
memcpy(ini,ans,MC*MC);
memcpy(ini_tile_count,tile_count,NT*4);
}
memcpy(ans,ini,MC*MC);
memcpy(tile_count,ini_tile_count,NT*4);
for(int i = 0 ; i < x ; i += 2){
++tile_count[ans[h_min+i][w_max+1]];
++tile_count[ans[h_min+i+1][w_max+1]];
++tile_count[ans[h_max-i][w_min-1]];
++tile_count[ans[h_max-i-1][w_min-1]];
bool b = 1;
repp(j,0,dw-y){
int c0 = -1 , c1 = -1;
repp(t,16,20) if((ans[h_min+i][w_max-j+2]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0){ b = 0; break;}
ans[h_min+i][w_max-j+1] = c0;
--tile_count[c0];
repp(t,16,20) if((ans[h_min+i+1][w_max-j+2]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1){ b = 0; break;}
ans[h_min+i+1][w_max-j+1] = c1;
--tile_count[c1];
c0 = -1; c1 = -1;
repp(t,16,20) if((ans[h_max-i][w_min+j-2]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0){ b = 0; break;}
ans[h_max-i][w_min+j-1] = c0;
--tile_count[c0];
repp(t,16,20) if((ans[h_max-i-1][w_min+j-2]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1){ b = 0; break;}
ans[h_max-i-1][w_min+j-1] = c1;
--tile_count[c1];
}
if(!b) break;
int c0 = -1 , c1 = -1;
repp(t,0,4) if((ans[h_min+i][w_min+y+1]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) break;
ans[h_min+i][w_min+y] = c0;
--tile_count[c0];
repp(t,12,16) if((ans[h_min+i+1][w_min+y+1]&3) != (t&3) && (c0&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) break;
ans[h_min+i+1][w_min+y] = c1;
--tile_count[c1];
c0 = -1; c1 = -1;
repp(t,8,12) if((ans[h_max-i][w_max-y-1]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0) break;
ans[h_max-i][w_max-y] = c0;
--tile_count[c0];
repp(t,4,8) if((ans[h_max-i-1][w_max-y-1]&3) != (t&3) && (c0&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1) break;
ans[h_max-i-1][w_max-y] = c1;
--tile_count[c1];
memcpy(ini,ans,MC*MC);
memcpy(ini_tile_count,tile_count,NT*4);
}
memcpy(ans,ini,MC*MC);
memcpy(tile_count,ini_tile_count,NT*4);
} else {
if((h_max-h_min)%2==1 && (w_max-w_min)%2==1){
for(int j = w_min ; j < w_max ; j += 2){
int c0 = -1 , c1 = -1 , c2 = -1 , c3 = -1;
repp(t,20,24) if((ans[h_min-2][j]&3) != (t&3) && ((c0<0 && tile_count[t]) || (c0>=0 && tile_count[c0] < tile_count[t]))) c0 = t;
if(!~c0){ b = 0; break;}
++tile_count[ans[h_min-1][j]];
ans[h_min-1][j] = c0;
--tile_count[c0];
repp(t,20,24) if((ans[h_min-2][j+1]&3) != (t&3) && ((c1<0 && tile_count[t]) || (c1>=0 && tile_count[c1] < tile_count[t]))) c1 = t;
if(!~c1){ b = 0; break;}
++tile_count[ans[h_min-1][j+1]];
ans[h_min-1][j+1] = c1;
--tile_count[c1];
repp(t,12,16) if((c0&3) != (t&3) && ((c2<0 && tile_count[t]) || (c2>=0 && tile_count[c2] < tile_count[t]))) c2 = t;
if(!~c2){ b = 0; break;}
++tile_count[ans[h_min][j]];
ans[h_min][j] = c2;
--tile_count[c2];
repp(t,8,12) if((c1&3) != (t&3) && (c2&3) != (t&3) && ((c3<0 && tile_count[t]) || (c3>=0 && tile_count[c3] < tile_count[t]))) c3 = t;
if(!~c3){ b = 0; break;}
++tile_count[ans[h_min][j+1]];
ans[h_min][j+1] = c3;
--tile_count[c3];
}
if(b){
memcpy(ini,ans,MC*MC);
memcpy(ini_tile_count,tile_count,NT*4);
++h_min;
}
}
while(b){
if(h_max - h_min < w_max - w_min){
if(!solve4_h()){
memcpy(ans,ini,MC*MC);
memcpy(tile_count,ini_tile_count,NT*4);
if(!solve4_w()) b = 0;
}
} else {
if(!solve4_w()){
memcpy(ans,ini,MC*MC);
memcpy(tile_count,ini_tile_count,NT*4);
if(!solve4_h()) b = 0;
}
}
if(b){
memcpy(ini,ans,MC*MC);
memcpy(ini_tile_count,tile_count,NT*4);
}
}
}
}
h_min = max(1,h_min-1); h_max = min(H,h_max+1);
w_min = max(1,w_min-1); w_max = min(W,w_max+1);
memcpy(ans,ini,MC*MC);
memcpy(tile_count,ini_tile_count,NT*4);
int iniscore = 0;
repp(i,0,NT) iniscore += tile_count[i];
iniscore /= 2;
while(get_time() < end_time){
nowscore = iniscore;
solve1();
if(bestscore > nowscore){
memcpy(best,ans,MC*MC);
bestscore = nowscore;
}
memcpy(tile_count,ini_tile_count,NT*4);
memcpy(ans,ini,MC*MC);
}
}
void solve1(){ //山登り
int cnt = 0;
while(cnt<30){
bool b = 0;
repp(i,h_min,h_max+1) repp(j,w_min,w_max+1) if(~ans[i][j]){
if(code[ans[i][j]>>2]&1) b |= horizontal(i,j);
if(code[ans[i][j]>>2]&2) b |= vertical(i,j);
}
++cnt;
if(b) cnt = 0;
}
}
public:
vector<int> create(int _H, int _W, vector<string> lights) {
//prepare
H = _H; W = _W;
h_min = 1; h_max = H;
w_min = 1; w_max = W;
repp(i,0,H*W){
tile[((lights[i][0]-'0')<<2)+(lights[i][1]-'a')].push_back(i);
}
color_num = 4;
while(tile[color_num-1].size() == 0) --color_num;
repp(i,0,NT) tile_count[i] = tile[i].size();
repp(i,1,H+1) fill(ans[i]+1,ans[i]+W+1,-1);
fill(ans[0],ans[0]+W+2,NT);
fill(ans[H+1],ans[H+1]+W+2,NT);
repp(i,1,H+1) ans[i][0] = ans[i][W+1] = NT;
bestscore = H*W;
//solve
solveA();
repp(i,0,NT) tile_count[i] = tile[i].size();
repp(i,1,H+1) fill(ans[i]+1,ans[i]+W+1,-1);
h_min = 1; h_max = H;
w_min = 1; w_max = W;
solveB();
//output
vector<int> ret(H*W,-1);
repp(i,1,H+1) repp(j,1,W+1) if(~best[i][j]){
auto &tmp = tile[best[i][j]];
ret[i*W+j-1-W] = *(tmp.rbegin());
tmp.pop_back();
}
int z = 0;
repp(i,1,H+1) repp(j,1,W+1) if(!~best[i][j]){
while(!tile[z].size()) ++z;
ret[i*W+j-1-W] = *(tile[z].rbegin());
tile[z].pop_back();
}
return ret;
}
};
反省
スコアの差は$7$位と$4k$、$1$位と$6k$ほどある。
TLEが3ケースで出ていたことで$1.5k$ほどスコアが下がったようだが、それでも上位とは離されている。
初日に焼きなましは不要だと感じたのだが、実行時間が余っていたのだから山登りを焼きなましにすることを検討すべきであった。
ただ焼きなましを導入するにあたっての障壁が、遷移として適切なものを見つけることである。
自分はこれを考えるのが面倒というところで止まってしまったので論外である。
面倒であることと有効でないことは一致しないので、面倒だという理由で考えるのをやめてしまってはいけない。
もう一つ自分がやるべきだったのは、理論値の計算である。
これをすれば上位の人が理論値に達していることにはっきり気付くことができたはずだ。
また目標を理論値に設定することができ、そのためには何が必要であるかを考えるきっかけにすることができただろう。
マラソンマッチは厳密解を出せるとは限らないのだが、絶対に出せないというわけでもないことは心に刻んでおきたい。
<(古い記事) Topcoder Marathon Match 96
関連
(新しい記事)>
<(古い記事) Topcoder Marathon Match 96