#include #include #include #include using namespace std; #define X first #define Y second #define REP(i,n) for(int i=0; i <(n); ++i) int n; char mapa[60][60]; int nr[60][60], mat[60][60], mat2[60*60][4]; typedef pair p2; typedef pair p3; vector pts; vector edges[60*60]; vector literki[10]; const int INF = 1<<29; int zbior[4]; bool debug; int zrob_zbior(int z) { int best=INF,deg; REP(i,pts.size()) REP(j,pts.size()) { int dg=0,x=mat[i][j]; REP(k,4) if (zbior[k]==z) { dg++; x += mat2[i][k] %d [%d]\n", z, best,deg); return best; } int main() { while(scanf("%d", &n) == 1 && n) { REP(i,60)REP(j,60) { mapa[i][j]=0;nr[i][j]=-1; mat[i][j]=INF;} REP(i,4) literki[i].clear(); pts.clear(); REP(i,60*60) edges[i].clear(); int len=n,dlen=1; REP(i, 2*n-1) { REP(j, len) { scanf(" %c", &mapa[i][j]); if (mapa[i][j]>='A' && mapa[i][j]<='D') { literki[mapa[i][j]-'A'].push_back(pts.size()); } pts.push_back(p2(i,j)); nr[i][j] = pts.size()-1; } if (len == 2*n-1) dlen = -1; len+=dlen; } len = n; dlen = 1; REP(i, pts.size()) { int x=pts[i].X, y=pts[i].Y; if (y+1 < len) { //if (nr[x][y+1]==-1) puts("AAAA"); edges[i].push_back(nr[x][y+1]); } if (y) { edges[i].push_back(nr[x][y-1]); } if (x < n-1) { edges[i].push_back(nr[x+1][y]); edges[nr[x+1][y]].push_back(i); edges[i].push_back(nr[x+1][y+1]); edges[nr[x+1][y+1]].push_back(i); } else if (len != n) { if (y) { edges[i].push_back(nr[x+1][y-1]); edges[nr[x+1][y-1]].push_back(i); } if (y < len-1) { edges[i].push_back(nr[x+1][y]); edges[nr[x+1][y]].push_back(i); } } if (i+1 < pts.size() && pts[i+1].X > pts[i].X) { if (len == 2*n-1) { dlen = -1; } len += dlen; } } REP(i,pts.size()) REP(j,edges[i].size()) if (edges[i][j]==-1) while(1); REP(i, pts.size()) REP(j, edges[i].size()) mat[i][edges[i][j]] = 1; REP(i, pts.size()) mat[i][i] = 0; REP(k, pts.size()) REP(i, pts.size()) REP(j, pts.size()) { mat[i][j] zbiory[4]; zbior[0]=0; int sol = INF; REP(a,2) REP(b, a+2) REP(c, (b+2)>?(a+2)) { // debug = (!a && !b && !c); // if (!debug) continue; zbior[1]=a; zbior[2]=b; zbior[3]=c; int ile=(a+1)>?(b+1)>?(c+1); REP(i,4) zbiory[i].clear(); REP(z, ile) REP(i,4) if (zbior[i]==z) REP(j, literki[i].size()) zbiory[z].push_back(literki[i][j]); // zrob zbiory: REP(i,pts.size()) { REP(z, 4) { mat2[i][z]=INF; REP(j,literki[z].size()) mat2[i][z] e; int mat3[4][4]; REP(i,4)REP(j,4) mat3[i][j]=(i==j?0:INF); // printf("ile=%d\n", ile); REP(z, ile) REP(k, z) { int best=INF; REP(i, zbiory[z].size()) REP(j, zbiory[k].size()) best