POJ 1361 Holedox Moving
1 算法
记录蛇头位置后,蛇的身体每一格的前一格对当前个而言只有4种可能,即上左下右,可用2bits进行存储,那么8格长的蛇只需要14bits。
2 代码
2.1 AC的代码
#include <queue>
#include <iostream>
#include <cstring>
using namespace std;
bool isv[20][20][(1 << 14) - 1];
struct node
{
int bx, by, lx, ly, pos;
int cost;
};
int n, m, l;
int bx, by, lx, ly, pos0;
int ones;
bool isused[20][20];
int offsetx[4] = {-1, 0, 1, 0};
int offsety[4] = {0, 1, 0, -1};
void read_data()
{
int fx, fy, px, py;
int x;
ones = (1 << (2 * (l - 1))) - 1;
memset(isused, 0, sizeof(isused));
cin >> bx >> by;
bx--;
by--;
fx = bx;
fy = by;
pos0 = 0;
for (int i = 1; i < l; ++i)
{
cin >> px >> py;
px--;
py--;
if (fx == px - 1)
x = 0;
if (fy == py + 1)
x = 1;
if (fx == px + 1)
x = 2;
if (fy == py - 1)
x = 3;
pos0 += x << ((i - 1) * 2);
fx = px;
fy = py;
}
cin >> x;
while (x--)
{
cin >> px >> py;
px--;
py--;
isused[px][py] = true;
}
lx = fx;
ly = fy;
}
bool isinside(int x, int y)
{
return (0 <= x && x < n && 0 <= y && y < m);
}
void get_newl(int lx, int ly, int &newlx, int &newly, int pos)
{
newlx = lx + offsetx[(pos >> ((l - 2) * 2))];
newly = ly + offsety[(pos >> ((l - 2) * 2))];
}
void dealused(int lx, int ly, int pos, bool val)
{
isused[lx][ly] = val;
for (int i = (l - 2) * 2; i >= 0; i = i - 2)
{
lx = lx + offsetx[(pos >> i) & 3];
ly = ly + offsety[(pos >> i) & 3];
isused[lx][ly] = val;
}
}
int bfs()
{
struct node temp;
struct node tempnext;
int x, y;
queue<struct node=""> q;
if (bx == 0 && by == 0) return 0;
memset(isv, 0, sizeof(isv));
temp.bx = bx;
temp.by = by;
temp.lx = lx;
temp.ly = ly;
temp.pos = pos0;
temp.cost = 0;
isv[bx][by][pos0] = true;
q.push(temp);
while (!q.empty())
{
temp = q.front();
dealused(temp.lx, temp.ly, temp.pos, true);
//cout << temp.pos << ' ' << temp.cost <<endl;
for (int i = 0; i < 4; ++i)
{
tempnext.bx = temp.bx + offsetx[i];
tempnext.by = temp.by + offsety[i];
tempnext.pos = ((temp.pos << 2) + i) & ones;
if (isinside(tempnext.bx, tempnext.by) && !isused[tempnext.bx][tempnext.by]
&& !isv[tempnext.bx][tempnext.by][tempnext.pos])
{
if (tempnext.bx == 0 && tempnext.by == 0) return temp.cost + 1;
get_newl(temp.lx, temp.ly, tempnext.lx, tempnext.ly, temp.pos);
tempnext.cost = temp.cost + 1;
q.push(tempnext);
isv[tempnext.bx][tempnext.by][tempnext.pos] = true;
}
}
dealused(temp.lx, temp.ly, temp.pos, false);
q.pop();
}
return -1;
}
int main()
{
int counter = 0;
cin >> n >> m >> l;
while (n != 0 && m != 0 && l != 0)
{
read_data();
counter++;
cout << "Case " << counter << ": " << bfs() << endl;
cin >> n >> m >> l;
}
return 0;
}