test02
原始文件为 cpp 代码,本文是转换后的 Markdown 文件。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <vector>
#include <set>
using namespace std;
struct State
{
int p[3];
void init() { p[1] = 257; p[2] = 258; }
void init(int a, int b, int c) {p[0]=a; p[1]=b; p[2]=c;}
void setv(int idx, int value) { p[idx]=value; }
};
const int maxstate = 8000000;
State st[maxstate], goal;
char save[17][17];
// set<int> vis;
bool vis[260][260][260];
vector<int> G[260];
int w, h, ghost_num;
char dict[26];
int dis[maxstate];
bool init()
{
scanf("%d%d%d", &w, &h, &ghost_num); ghost_num = 0;
st[1].init(); goal.init();
for(int i = 0; i < 260; ++i) G[i].clear();
for(int i = 0; i < 260; ++i) G[i].push_back(i);
memset(dis, 0, sizeof(dis));
memset(dict, 0, sizeof(dict));
memset(save, 0, sizeof(save));
memset(vis, false, sizeof(vis));
// vis.clear();
return (w && h);
}
void input();
int bfs();
int main()
{
// freopen("in.txt", "r", stdin);
while(true)
{
if(!init()) break;
input();
int ans = bfs();
printf("%d\n", dis[ans]);
}
}
void link(int a, int b)
{
G[b].push_back(a);
G[a].push_back(b);
}
int query(int ch_int)
{
if(!dict[ch_int])
{
++ghost_num;
dict[ch_int] = ghost_num;
return (ghost_num - 1);
}
return dict[ch_int] - 1;
}
void input()
{
char line;
for(int i = 0; i < h; ++i)
{
scanf("%c", &line);
for(int j = 0; j < w; ++j)
{
scanf("%c", &save[i][j]);
}
}
for(int j = 1; j < w; ++j)
{
if(save[0][j] == '#') continue;
if(save[0][j-1] != '#') link(j, j-1);
}
for(int i = 1; i < h; ++i)
{
if(save[i][0] == '#') continue;
if(save[i-1][0] != '#') link((i << 4), (i - 1) << 4);
}
for(int i = 1; i < h; ++ i)
{
for(int j = 1; j < w; ++j)
{
if(save[i][j] == '#') continue;
int now_idx = (i << 4) + j;
if(save[i-1][j] != '#') link(now_idx, now_idx - 16);
if(save[i][j-1] != '#') link(now_idx, now_idx - 1);
}
}
for(int i = 0; i < h; ++i)
{
for(int j = 0; j < w; ++j)
{
char ch = save[i][j];
if(ch >= 'a' && ch <= 'z')
{
int now_idx = query(ch - 'a');
st[1].setv(now_idx, (i << 4) + j);
}else if(ch >= 'A' && ch <= 'Z')
{
int now_idx = query(ch - 'A');
goal.setv(now_idx, (i << 4) + j);
}
}
}
}
bool isequal(State a, State b)
{
for(int i = 0; i < 3; ++i)
{
if(a.p[i] != b.p[i]) return false;
}
return true;
}
bool try_to_insert(int rear)
{
if(vis[st[rear].p[0]][st[rear].p[1]][st[rear].p[2]]) return false;
vis[st[rear].p[0]][st[rear].p[1]][st[rear].p[2]] = true;
return true;
// int v = 0;
// for(int i = 0; i < 3; ++i)
// v = (v << 10) + st[rear].p[i];
// if(vis.count(v)) return false;
// vis.insert(v); return true;
}
const int dx[] = {0, -16, 1, 16, -1};
int bfs()
{
int front = 1, rear = 2;
while(front < rear) {
State& s = st[front];
if(isequal(s, goal)) return front;
int g1 = s.p[0]; int g2 = s.p[1]; int g3 = s.p[2];
for(int x = 0; x < G[g1].size(); ++x)
{
int newg1 = G[g1][x];
for(int y = 0; y < G[g2].size(); ++y)
{
int newg2 = G[g2][y];
for(int z = 0; z < G[g3].size(); ++z)
{
int newg3 = G[g3][z];
if(!x && !y && !z) continue;
if(newg1 == newg2 || newg2 == newg3 || newg1 == newg3 ) continue;
if(newg1 == g2 && newg2 == g1) continue;
if(newg1 == g3 && newg3 == g1) continue;
if(newg2 == g3 && newg3 == g2) continue;
State& r = st[rear];
r.init(newg1, newg2, newg3);
dis[rear] = dis[front] + 1;
if(try_to_insert(rear)) ++rear;
}
}
}
++front;
}
return 0;
}