POJ3322解题报告


  初学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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值