poj1475/acwing174 推箱子

这题思路挺新的,,可是相比实现并不那么恶心

因为要求箱子的移动次数少 可以bfs,用三元组(x,y,dir)表示箱子在(x,y),dir是人所在的箱子的方向
因为在箱子移动次数少的基础上还要人移动尽可能少 所以每次判断人的移动时要再bfs一次(也就是bfs里套了一个bfs)

实际实现时我的队列里存储了6个量
q[x][0]:dir
q[x][1]:x
q[x][2]:y
q[x][3]:上一个状态(因为最后要求输出路径)
q[x][4]:箱子目前移动的步数
q[x][5]:人目前移动的步数

注意恶心至极的一点:每次第一次bfs到(x,y,dir)这个状态还不一定是最优的 要按照箱子的次数,人的次数来比较 特别的,对于acwing上“NSWE”的优先顺序要求 还要考虑推来的方向适不适合(以及注意判断当前对应的方向要按照“EWSN”来 因为上一步的方向比较靠后 要是靠前的更优先靠后的就不那么优先,可见代码)

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<queue>

using namespace std;
int n,m;
int sa,sb,ba,bb,ea,eb;
char s[25][25];
int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
int lt[4]={'n'-'a','s'-'a','w'-'a','e'-'a'};
bool vis[25][25];
int vis2[25][25][4];
string str[25][25];
string bfs(int x,int y,int a,int b)
{
	if(!(x>=1&&x<=n&&y>=1&&y<=m&&a>=1&&a<=n&&b>=1&&b<=m))return "!";
	if(x==a&&y==b)return "";
	memset(vis,0,sizeof(vis));
	queue<pair<int,int> >qq;
	while(!qq.empty())qq.pop();
	qq.push(make_pair(x,y));
	str[x][y]="";
	while(!qq.empty())
	{
		int u=qq.front().first,v=qq.front().second;
		qq.pop();
		for(int i=0;i<4;++i)
		{
			int p=i;
			i=i^1;
			int tx=u+dx[i],ty=v+dy[i];
			if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&s[tx][ty]!='#'&&!vis[tx][ty])
			{
				str[tx][ty]=str[u][v]+char(lt[i^1]+'a');
				if(tx==a&&ty==b)return str[tx][ty];
				vis[tx][ty]=true;
				qq.push(make_pair(tx,ty));
			}
			i=p;
		}
	}
	return "!";
}
int q[5000][6],head,tail;
void trace(int x)
{
	if(q[x][3]==-1)
	{
		s[ba][bb]='#';
		cout<<bfs(sa,sb,q[x][1]+dx[q[x][0]],q[x][2]+dy[q[x][0]]);
		s[ba][bb]='.';
		return;
	}
	int k=q[x][3];
	trace(k);
	s[q[k][1]][q[k][2]]='#';
	cout<<bfs(q[k][1]+dx[q[k][0]],q[k][2]+dy[q[k][0]],q[k][1]+dx[q[x][0]],q[k][2]+dy[q[x][0]]);
	s[q[k][1]][q[k][2]]='.';
	putchar(lt[q[x][0]]+'A');
}
void bfs2()
{
	while(head<=tail)
	{
		int dir=q[head][0],x=q[head][1],y=q[head][2];
		for(int i=0;i<4;++i)
		{
			int tx=x+dx[i],ty=y+dy[i]; 
			int px=x-dx[i],py=y-dy[i];
			if(px>=1&&px<=n&&py>=1&&py<=m&&s[px][py]!='#')
			{
				s[x][y]='#';
				if(bfs(x+dx[dir],y+dy[dir],tx,ty)=="!")
				{
					s[x][y]='.';
					continue;
				}
				int len=bfs(x+dx[dir],y+dy[dir],tx,ty).size();
				s[x][y]='.';
				if(vis2[px][py][i])
				{
					int k=vis2[px][py][i];
					if(q[k][4]<q[head][4]+1||q[k][4]==q[head][4]+1&&q[k][5]<=q[head][5]+len||q[k][4]==q[head][4]+1&&q[k][5]==q[head][5]+len&&q[k][0]>i)continue;
					else if(vis2[px][py][i]>head)
					{
						q[k][0]=i,q[k][3]=head,q[k][5]=q[head][5]+len;
						continue;
					}
				}
				vis2[px][py][i]=++tail;
				q[tail][0]=i,q[tail][1]=px,q[tail][2]=py,q[tail][3]=head,q[tail][4]=q[head][4]+1,q[tail][5]=q[head][5]+len;
			}
		}
		++head;
	}
	int ans=-1;
	for(int i=0;i<4;++i)
	{
		if(vis2[ea][eb][i])
		{
			int k=vis2[ea][eb][i]; 
//			printf("%c\n",lt[q[k][0]]+'A');
			if(ans==-1||q[k][4]<q[ans][4]||q[k][4]==q[ans][4]&&q[k][5]<q[ans][5]||q[k][4]==q[ans][4]&&q[k][5]==q[ans][5]&&q[k][0]>q[ans][0])ans=k;
		}
	}
//	printf("%c\n",lt[q[ans][0]]+'A');
	if(ans==-1)printf("Impossible.\n");
	else trace(ans),printf("\n");
	printf("\n");
}
int main()
{
//	freopen("pushing.in","r",stdin);
//	freopen("pushing.out","w",stdout);
	int tot=0;
	while(scanf("%d%d",&n,&m)&&n)
	{
		printf("Maze #%d\n",++tot);
		for(int i=1;i<=n;++i)
		{
//			i=i^1;
			scanf("%s",s[i]+1);
			for(int j=1;j<=m;++j)
			{
				if(s[i][j]=='S')sa=i,sb=j,s[i][j]='.';
				else if(s[i][j]=='B')ba=i,bb=j,s[i][j]='.';
				else if(s[i][j]=='T')ea=i,eb=j,s[i][j]='.';
			}
		}
		
		head=1,tail=0;
		memset(vis2,0,sizeof(vis2));
		s[ba][bb]='#';
		for(int i=0;i<4;++i)
		{
			int ta=ba+dx[i],tb=bb+dy[i];
			if(s[ta][tb]=='#')continue;
			if(bfs(sa,sb,ta,tb)!="!")
			{
				vis2[ba][bb][i]=++tail;
				q[tail][0]=i,q[tail][1]=ba,q[tail][2]=bb,q[tail][3]=-1,q[tail][4]=0,q[tail][5]=bfs(sa,sb,ta,tb).size();
			}
		}
		s[ba][bb]='.';
		bfs2();
	}
	return 0;
}

附上一组数据,,我在自己做的时候很受用

input
1 7
SB....T
1 7
SB..#.T
7 11
###########
#T##......#
#.#.#..####
#....B....#
#.######..#
#.....S...#
###########
8 4
....
.##.
.#..
.#..
.#.B
.##S
....
###T
5 11
#T##......#
#.#.#..####
#....B....#
#.######..#
#.....S...#
4 5
##T..
.SB..
.#...
...##
7 8
........
.######.
.....T#.
#.#####.
#...BS..
#..#####
########
10 5
...##
.#.##
.#.##
.#.##
.#.##
.#.##
.#...
SB...
##...
##T..
1 3
STB
1 3
SBT
1 3
TBS
3 1
T
B
S
3 3
S..
.B.
T.#
12 14
S.#...........
.B.#..........
....#.........
#....#........
.#....#.......
..#....#......
...#....#.....
....#....#....
.....#....#...
......#....#..
.......#....#.
........#...T#
11 19
....#####..........
....#...#..........
....#...#..........
..###..B##.........
..#......#.........
###.#.##.#...######
#...#.##.#####T...#
#.................#
####..###.#S##....#
...#......#########
...########........
20 20
S...................
.##################.
..................#.
.#.#..............#.
.#.###########.#..#.
.#.#...........#..#.
.#.#..########.#..#.
.#.#.........#.#..#.
.#.########..#.#..#.
.#.#.....B...#.#....
.#.#.######..#.#..#.
.#.#.........#.#..#.
.#.#..########.#..#.
.#.#............#.#.
.#.#............#.#.
.#.#.############.#.
..................#.
.#................#.
.##################.
...................T
20 20
....................
.##################.
..................#.
#################.#.
................#.#.
.##############.#.#.
.#............#.#.#.
.#.##########.#.#.#.
.#.#........#.#.#.#.
.#.#.####...#.#.#.#.
.#.#.#..SB..#.#.#.#.
.#.#.#.##T..#.#.#.#.
.#.#.#.######.#.#.#.
.#.#.#........#.#.#.
.#.#.##########.#.#.
.#.#............#.#.
.#.##############.#.
.#................#.
.##################.
....................
20 20
....................
.##################.
..................#.
#################.#.
................#.#.
.##############.#.#.
.#............#.#.#.
.#.##########.#.#.#.
.#.#........#.#.#.#.
.#.#.####...#.#.#.#.
.#.#.#.SB...#.#.#.#.
.#.#.#..#.###.#.#.#.
.#.#.#.....##.#.#.#.
.#.#.#.T.#....#.#.#.
.#.#.##########.#.#.
.#.#............#.#.
.#.##############.#.
.#................#.
.##################.
....................
20 20
#################..#
SB.................#
################.#.#
.................#.#
..############.#.#.#
#..............#.#.#
#.#.########.#.#.#.#
#.#..........#.#.#.#
#.#.#.####.#.#.#.#.#
#.#.#......#.#.#.#.#
#.#.#.#.##.#.#.#.#.#
#.#.#.#.##T#.#.#.#.#
#.#.#.#........#.#.#
#.#.#.#.######.#.#.#
#.#.#............#.#
#.#.#.##########.#.#
#.#................#
#.#.##############..
#...................
#..#################
20 20
..#.................
.#SB.#...........##.
.#.#.#.#.#####.###..
.#.....#.....#...#..
.#.###.#...#.....#.#
.#...#####.#####.#..
.....#.....#.#...##.
.###.#.#...#.#......
.#...#.#.###.#.####.
.#.....#.....#...#..
.#.###.#...#.....#.#
.#...#####.#####.#..
.....#.....#.#...##.
.###.#.#...#.#......
.#...#.#.###.#.###.#
.#.....#.....#...#..
.#.###.#...#.....##.
.#...#####.#####.#..
...........#.......#
.#########...####..T
20 20
S...................
.T..................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
..................B.
....................
20 20
T...................
.S..................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
...................B
20 20
####################
#SB#################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
####################
###################T
20 1
S
.
B
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
T
20 3
S..
##.
...
.##
...
##.
...
.##
...
##.
...
.##
...
##.
...
.##
...
##.
...
.BT
1 20
TB.................S
0 0

output的话就运行我的程序吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值