hdu 1429——典型的状态压缩

原网站:http://acm.hdu.edu.cn/showproblem.php?pid=1429


题目中文的,意思在不懂,我只能说:"苟。。。"


好了,不扯没用的了,直接贴代码吧。


代码乍一看很有意思,因为用二进制的方法来记录钥匙与门的匹配,不太常见,其实是典型的状态压缩的题目,可以一试。


其实就是紫书上现学现卖的。。。。。。。。。。。


#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
int dx[] = { 1,-1,0,0 };
int dy[] = { 0,0,-1,1 };
char dzm[] = { 'A','B','C','D','E','F','G','H','I','J' };
char xzm[] = { 'a','b','c','d','e','f','g','h','i','j' };
struct point {
	int x, y;
	int step, dir;
};
int n, m, sx, sy;
int visit[30][30][1050];//记录钥匙
char map[30][30];
int bfs()
{
	int i, j;
	memset(visit, 0, sizeof(visit));
	queue<point>Q;
	point now, next;
	now.x = sx; now.y = sy;
	now.step = now.dir = 0;
	visit[now.x][now.y][now.dir] = 1;
	Q.push(now);
	while (!Q.empty())
	{
		now = Q.front();
		Q.pop();
		if (map[now.x][now.y] == '^')
			return now.step;
		for (i = 0; i<4; i++)
		{
			next.x = now.x + dx[i];
			next.y = now.y + dy[i];
			next.step = now.step + 1;
			next.dir = now.dir;
			if (map[next.x][next.y] == '*')continue;
			if (next.x<1 || next.x>n || next.y<1 || next.y>m)continue;
			if (map[next.x][next.y] <= 'J'&&map[next.x][next.y] >= 'A')
			{
				for (j = 0; j<10; j++)
				{
					if (map[next.x][next.y] == dzm[j])
					{
						if ((next.dir&(1 << j)) != 0)
						{
							if (visit[next.x][next.y][next.dir] == 0)
							{
								visit[next.x][next.y][next.dir] = 1;
								Q.push(next);
							}
						}
					}
				}
			}
			else  if (map[next.x][next.y] <= 'j'&&map[next.x][next.y] >= 'a')
			{
				for (j = 0; j<10; j++)
				{
					if (map[next.x][next.y] == xzm[j])
					{
						if ((next.dir&(1 << j)) == 0)
							next.dir += (1 << j);
						if (visit[next.x][next.y][next.dir] == 0)
						{
							visit[next.x][next.y][next.dir] = 1;
							Q.push(next);
						}
					}
				}
			}
			else
			{
				if (visit[next.x][next.y][next.dir] == 0)
				{
					visit[next.x][next.y][next.dir] = 1;
					Q.push(next);
				}
			}
		}
	}
	return -1;
}
int main()
{
	int i, j, t;
	while (scanf("%d %d %d", &n, &m, &t)!=EOF)
	{
		getchar();
		for (i = 1; i <= n; i++)
		{
			for (j = 1; j <= m; j++)
			{
				scanf(" %c", &map[i][j]);
				if (map[i][j] == '@')
					sx = i, sy = j;
			}
		}
		int q = bfs();
		if (q >= t)
			printf("-1\n");
		else
			printf("%d\n", q);
	}
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值