初学BFS接触到的第一个比较有难度的题,没想在网上找代码就自己吭哧了半天。
开始以为可以用map<自定义struct,int>,编完才发现不可以。
后来想想也就是用map的一个count功能,就自己编了一个count结构体的函数,用了vector。然后TLE,想来也是判断结点是否已经存在过太浪费时间。然后想通了,用三位数组id[3][maxn][maxn]判断是否存在过这个结点。
后来WA是因为没有清空队列。
最后用C++ TLE,但是G++ 过了,1969ms的极限时间(要求2000ms)。
还有很多不完善的地方,日后如果看到再反思。
#include<cstdio>
#include<queue>
#include<vector>
#include<cstring>
using namespace std;
struct node
{
int pose, r0, c0, r1, c1,step;
};
const int maxn = 501;
char status[maxn][maxn];
queue<node> q;
int r, c;
int id[3][maxn][maxn];
node walk1(node head,int way)
{
node next;
switch (way)
{
case 0: next.c0 = head.c0 - 2; next.c1 = head.c0 - 1; next.r0 = head.r0; next.r1 = head.r0; next.pose = 2; break;//左
case 1: next.c0 = head.c0; next.c1 = head.c0; next.r0 = head.r0 - 2; next.r1 = head.r0 - 1; next.pose = 1; break;//上
case 2: next.c0 = head.c0 + 1; next.c1 = head.c0 + 2; next.r0 = head.r0; next.r1 = head.r0; next.pose = 2; break;//右
case 3: next.c0 = head.c0; next.c1 = head.c0; next.r0 = head.r0 + 1; next.r1 = head.r0 + 2; next.pose = 1; break;//下
}
return next;
}
node walk2(node head, int way)
{
node next;
if (head.pose==2)
switch (way)
{
case 0: next.pose = 0; next.c0 = head.c0 - 1; next.c1 = -1; next.r0 = head.r0; next.r1 = -1; break;
case 1: next.pose = 2; next.c0 = head.c0; next.c1 = head.c1; next.r0 = head.r0 - 1; next.r1 = head.r0 - 1; break;
case 2: next.pose = 0; next.c0 = head.c1 + 1; next.c1 = -1; next.r0 = head.r0; next.r1 = -1; break;
case 3: next.pose = 2; next.c0 = head.c0; next.c1 = head.c1; next.r0 = head.r0 + 1; next.r1 = head.r0 + 1; break;
}
else
switch (way)
{
case 0: next.pose = 1; next.c0 = head.c0 - 1; next.c1 = head.c0 - 1; next.r0 = head.r0; next.r1 = head.r1; break;
case 1: next.pose = 0; next.c0 = head.c0; next.c1 = -1; next.r0 = head.r0 - 1; next.r1 = -1; break;
case 2: next.pose = 1; next.c0 = head.c0 + 1; next.c1 = head.c0 + 1; next.r0 = head.r0; next.r1 = head.r1; break;
case 3: next.pose = 0; next.c0 = head.c0; next.c1 = -1; next.r0 = head.r1 + 1; next.r1 = -1; break;
}
return next;
}
int bfs(node ini, node goal)
{
if (ini.pose == 0 && ini.r0 == goal.r0 && ini.c0 == goal.c0) return 0;
ini.step = 0;
q.push(ini);
id[ini.pose][ini.r0][ini.c0] = 1;
while (!q.empty())
{
node head = q.front(); q.pop();
if (head.pose == 0)
{
for (int i = 0; i < 4; i++)
{
node next;
next = walk1(head, i);
if (id[next.pose][next.r0][next.c0] || next.c0<0 || next.c0>c || next.c1<0 || next.c1>c || next.r0<0 || next.r0>r || next.r1<0 || next.r1>r || status[next.r0][next.c0] == '#' || status[next.r1][next.c1] == '#') continue;
next.step = head.step + 1;
//printf("next.step=%d,(%d,%d)和(%d,%d)\n", next.step,next.r0,next.c0,next.r1,next.c1);
q.push(next);
id[next.pose][next.r0][next.c0] = 1;
}
}
else if (head.pose == 1)
{
for (int i = 0; i < 4; i++)
{
node next;
next = walk2(head, i);
if (next.pose == 1) { if ( id[next.pose][next.r0][next.c0] || next.c0<0 || next.c0>c || next.c1<0 || next.c1>c || next.r0<0 || next.r0>r || next.r1<0 || next.r1>r || status[next.r0][next.c0] == '#' || status[next.r1][next.c1] == '#') continue; }
else if ( id[next.pose][next.r0][next.c0] == 1 || next.c0<0 || next.c0>c || next.r0<0 || next.r0>r || status[next.r0][next.c0] == '#' || status[next.r0][next.c0] == 'E') continue;
next.step = head.step + 1;
//printf("next.step=%d,(%d,%d)和(%d,%d)状态:%c\n", next.step, next.r0, next.c0, next.r1, next.c1, status[next.r0][next.c0]);
q.push(next);
id[next.pose][next.r0][next.c0] = 1;
if (next.pose == 0 && next.c0 == goal.c0 && next.r0 == goal.r0) return next.step;
}
}
else
{
for (int i = 0; i < 4; i++)
{
node next;
next = walk2(head, i);
if (next.pose == 2) { if (id[next.pose][next.r0][next.c0] || next.c0<0 || next.c0>c || next.c1<0 || next.c1>c || next.r0<0 || next.r0>r || next.r1<0 || next.r1>r || status[next.r0][next.c0] == '#' || status[next.r1][next.c1] == '#') continue; }
else if ( id[next.pose][next.r0][next.c0] || next.c0<0 || next.c0>c || next.r0<0 || next.r0>r || status[next.r0][next.c0] == '#' || status[next.r0][next.c0] == 'E') continue;
next.step = head.step + 1;
//printf("next.step=%d,(%d,%d)和(%d,%d) 状态:%c 姿势:%d 是否有:%d\n", next.step, next.r0, next.c0, next.r1, next.c1, status[next.r0][next.c0], next.pose, id[next.pose][next.r0][next.c0]);
q.push(next);
id[next.pose][next.r0][next.c0] = 1;
if (next.pose == 0 && next.c0 == goal.c0 && next.r0 == goal.r0) return next.step;
}
}
}
return -1;
}
int main()
{
while (scanf("%d%d", &r, &c) != EOF && r && c)
{
node ini;
node goal;
int flag = 1;
getchar();
for (int i = 0; i < r; i++)
{
for (int j = 0; j < c; j++)
{
scanf("%c", &status[i][j]);
if (status[i][j] == 'X')
{
if (flag)
{
flag = 0;
ini.pose = 0;
ini.r0 = i;
ini.c0 = j;
ini.r1 = -1;
ini.c1 = -1;
}
else
{
ini.r1 = i;
ini.c1 = j;
if (ini.c0 == ini.c1) ini.pose = 1;
else ini.pose = 2;
}
}
else if (status[i][j] == 'O')
{
goal.pose = 0;
goal.r0 = i;
goal.c0 = j;
goal.r1 = -1;
goal.c1 = -1;
}
}
getchar();
}
memset(id, 0, sizeof(id));
while (!q.empty()) q.pop();
int res=bfs(ini,goal);
if (res == -1) printf("Impossible\n");
else printf("%d\n", res);
}
return 0;
}