計蒜客 藏寶圖 (bfs + 狀壓)

傳送門

思路:

典型的bfs + 狀壓啊,一個入口出口,還要拿到地圖中多個東西,而且同一個點重複走的話不好標記,這時候就標記狀態啊/。。

md,退役垃圾狗。。。

答案 :48

    

PS:

    這裏走回出口沒必要在跑一遍bfs,只需要走到出口時判斷一下是否所有箱子都拿到了即可。

#include <bits/stdc++.h>

using namespace std;
int a[15][11] = {
	{0,0,0,0,0,0,0,0,0,0,0},
	{0,1,0,0,0,0,0,0,2,0,0},
	{0,0,0,0,-1,0,0,2,0,0,0},
	{0,0,-1,0,0,2,0,0,-1,0,0},
	{0,0,2,0,0,0,-1,0,0,2,0},
	{0,0,-1,0,0,2,0,-1,0,0,0},
	{0,0,0,-1,0,0,0,0,-1,0,0},
	{0,0,0,0,0,0,-1,0,0,2,0},
	{0,0,-1,0,-1,0,0,2,0,0,0},
	{0,0,2,0,0,0,0,-1,-1,0,0},
	{0,0,0,-1,0,0,-1,2,0,0,0}
};
int go[4][2] = {0,1,1,0,0,-1,-1,0};
struct node
{
	int x,y,sta,step;
	node(int xx = 0,int yy = 0,int state = 0,int s = 0)
	{
		x = xx,y = yy,sta = state,step = s;
	}

};
bool vis[20][20][1050];
int num[20][20];
int get_sta(int x,int y,int cur)
{
	int p[20];
	for(int i = 0;i < 10;++i)
	{
		p[i] = (cur >> i) & 1;
	}
	p[num[x][y]] = 1;
	int now = 0;
	for(int i = 9;i >= 0;--i)
		now = now * 2 + p[i];
	return now;
}

int bfs(int st,int dt)
{
	memset(vis,0,sizeof vis);
	queue<node>Q;
	while(!Q.empty()) Q.pop();
	Q.push(node(st,dt,0,0));
	vis[st][dt][0] = 1;
	while(!Q.empty())
	{
		node q = Q.front();Q.pop();
		if(q.x == 1 && q.y == 1 && q.sta == 1023)
			return q.step;
		for(int i = 0;i < 4;++i)
		{
			int tx = q.x + go[i][0];
			int ty = q.y + go[i][1];
			int sta = q.sta;
			if(a[tx][ty] == 2)
			{
				sta = get_sta(tx,ty,sta);
			}
			if(tx < 1 || ty < 1|| tx > 10 || ty > 10 || a[tx][ty] == -1 || vis[tx][ty][sta])
				continue;
			vis[tx][ty][sta] = 1;
			Q.push(node(tx,ty,sta,q.step + 1));
		}
	}
	return -1;
}
int main()
{
	memset(num,-1,sizeof num);
	int cnt = 0;
	for(int i = 1;i <= 10;++i)
	{
		for(int j = 1;j <= 10;++j)
		{
			if(a[i][j] == 2)
			{
				//printf("%d %d\n",i,j);
				num[i][j] = cnt++;
			}
		}
	}
	//cout << cnt << endl;
	cout << bfs(1,1) << endl;
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章