4 4 9 9 1 2 1 3 2 1 2 2 2 0 2 1 2 2 0 2 1 3 1 0 2 3 3 3 0 2 4 3 4 1 3 2 3 3 0 3 3 4 3 0 4 3 4 4 0 2 2 1 2 4 2 1
14
链接:http://acm.hdu.edu.cn/showproblem.php?pid=5094
很明显的状压bfs,但是错了很多地方,比赛的时候一直wa。 一个是初始点,忘记更新钥匙状态了, 还有就是一个地方== 打成了=。 o(︶︿︶)o 唉
题意:n*m大的迷宫 ,有p种钥匙。钥匙最多有10种,所以可以用状压表示门需要钥匙的状态, 还有已经拥有哪几把钥匙的状态。
然后下来一个k,然后k行表示 (x1,y1),(x2,y2)直接有门或者墙。 如果g==0 ,就是有墙, 如果g>0 表示有门,且门需要第g把钥匙才能开。
然后下来一个s,然后s行,表示(x,y)这个点有 第g把钥匙。
问从(1,1)到(n,m)最少几步。
做法:状压, 每个点有四个方向,记录能否通过的状态, 门的话 标记为-1, 0,表示不用钥匙,>0 的话,哪位上是1,表示要第几把钥匙。
然后结构体key 用二进制表示有了哪几把钥匙
然后lim[i][j][k],表示(i,j)点 有k状态 钥匙 有过没有, 没有就入队,否者不走这个点。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <ctype.h>
#include <math.h>
#include <string>
#include <iostream>
#include <algorithm>
using namespace std;
#include <stack>
#include <queue>
#include <vector>
#include <deque>
#include <set>
#include <map>
int dir[4][2]={
0,1,
-1,0,
0,-1,
1,0
};
int n,m,p;
int mp[60][60];
int bar[60][60][4];
int lim[60][60][1200];
struct point
{
int x,y,bu,key;
};
int ok(int x,int y)
{
if(x<0||y<0||x>=n||y>=m)
return 0;
return 1;
}
int bfs()
{
point sta;
sta.x=sta.y=0;
sta.bu=0;
sta.key=mp[0][0];
point nex,nw;
queue<point> q;
q.push(sta);
while(!q.empty())
{
nw=q.front();
q.pop();
if(nw.x==n-1&&nw.y==m-1)
return nw.bu;
for(int i=0;i<4;i++)
{
int xx=nw.x+dir[i][0];
int yy=nw.y+dir[i][1];
if(!ok(xx,yy))
continue;
if(bar[nw.x][nw.y][i]==-1)
continue;
if((bar[nw.x][nw.y][i]&nw.key)==bar[nw.x][nw.y][i])
{
nex=nw;
nex.x=xx;
nex.y=yy;
nex.key|=mp[xx][yy];
nex.bu++;
if(lim[xx][yy][nex.key]==0)
{
lim[xx][yy][nex.key]=1;
q.push(nex);
}
}
}
}
return -1;
}
int main()
{
while(scanf("%d%d%d",&n,&m,&p)!=EOF)
{
int k;
scanf("%d",&k);
memset(mp,0,sizeof mp);
memset(lim,0,sizeof lim);
memset(bar,0,sizeof bar);
for(int i=0;i<k;i++)
{
int x1,x2,y1,y2,g;
scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&g);
x1--;
y1--;
x2--;
y2--;
int tem;
if(g==0)
tem=-1;
else
tem=(1<<(g-1));
for(int j=0;j<4;j++)
{
int xx,yy;
xx=x1+dir[j][0];
yy=y1+dir[j][1];
if(xx==x2&&yy==y2)
{
if(tem!=-1)
bar[x1][y1][j]|=tem;
else
bar[x1][y1][j]|=-1;
}
xx=x2+dir[j][0];
yy=y2+dir[j][1];
if(xx==x1&&yy==y1)
{
if(tem!=-1)
bar[x2][y2][j]|=tem;
else
bar[x2][y2][j]|=-1;
}
}
}
int s;
scanf("%d",&s);
for(int i=0;i<s;i++)
{
int x,y,q;
scanf("%d%d%d",&x,&y,&q);
x--;
y--;
mp[x][y]|=(1<<(q-1));
}
int ans=bfs();
printf("%d\n",ans);
}
return 0;
}
/*
3 3 2
4
1 2 1 3 0
1 3 2 3 0
2 3 3 3 1
3 2 3 3 2
2
1 3 1
3 1 2
*/
原文地址:http://blog.csdn.net/u013532224/article/details/45509619