您的位置:首页 > 其它

CJOJ 2244 皇宫VS迷宫

2017-03-05 20:46 134 查看
广搜神题。。。

没难度,但很多点要考虑

比如

首先肯定要状态压缩233才9对字母

旁边有管道的话

就要看看

对面是墙或者管道肯定不可以走

如果管道初始状态可以通过直接通过

否则看看有没有key233

最重要的是到了一个点后要四处找钥匙233(坑我50分)

不说了233上代码

#include<cstdio>
#include<algorithm>
#include<cstring>
#define gx (nx+X[i])
#define gy (ny+Y[i])
int n,m;
struct Data {
int G,x,y;
};
const int X[]= {233,0,1,0,-1},Y[]= {23333,1,0,-1,0};
int key[24][24],tun[24][24],f[24][24],Bx,By,Ex,Ey;
int ans[1<<9][21][21];
// 存放钥匙 存放管道 管道初始状态 ,0横1竖
char M[24][24];
// 存放迷宫
struct queue {
Data data[20001];
int hd,tl;
queue() {
hd=tl=1;
}
inline void push(int g,int xx,int yy,int _ans) {
if(ans[g][xx][yy]==-1) {
#ifdef xzz
printf("push %d %d %d %d\n",g,xx,yy,_ans);
#endif
data[tl++]=(Data) {g,xx,yy};
ans[g][xx][yy]=_ans;
}
}
inline void front(int*a,int*b,int*c) {
*a=data[hd].G,*b=data[hd].x,*c=data[hd].y;
}
inline void pop() {
++hd;
}
inline bool full() {
return hd^tl;
}
};
queue que;
inline bool yes(int x,int y)
{
return x>0&&x<=n&&y>0&&y<=m;
}

void make();
void work();
int main()
{
scanf("%d%d",&n,&m);
for(int i=1; i<=n; i++)scanf("%s",M[i]+1);
make(),work();
return 0;
}
void make()
{
memset(ans,-1,sizeof ans);
memset(tun,-1,sizeof tun);
memset(key,-1,sizeof key);
for(int i=1; i<=n; i++)
for(int j=1; j<=m; j++) {
if(M[i][j]>'0'&&M[i][j]<='9')key[i][j]=M[i][j]-'0'-1;
else if(M[i][j]>='A'&&M[i][j]<'J')tun[i][j]=M[i][j]-'A',f[i][j]=1;
else if(M[i][j]>='a'&&M[i][j]<'j')tun[i][j]=M[i][j]-'a',f[i][j]=0;
else if(M[i][j]=='#')Bx=i,By=j;
else if(M[i][j]=='$')Ex=i,Ey=j;
}
}
void work()
{
que.push(0,Bx,By,0);
while(que.full()) {
int g,G,x,y;
que.front(&g,&x,&y),G=g;
#ifdef xzz
printf("%d %d %d %d\n",G,x,y,ans[G][x][y]);
#endif
if((x==Ex&&y==Ey)||ans[g][x][y]==10001) {
printf("%d",ans[g][x][y]);
return;
}
if(key[x][y]!=-1)g|=(1<<key[x][y]);
for(int i=1; i<=4; i++){
register int nx=x+X[i],ny=y+Y[i];
if(key[nx][ny]!=-1)g|=(1<<key[nx][ny]);
}
for(int i=1; i<=4; i++) {
register int nx=x+X[i],ny=y+Y[i];
#ifdef xzz
printf("nx %d ny %d\n",nx,ny);
#endif
if(yes(nx,ny)&&M[nx][ny]!='*') {
if(tun[nx][ny]!=-1)
if(yes(gx,gy)&&
M[gx][gy]!='*'&&(M[gx][gy]<'a'||M[gx][gy]>'z')&&(M[gx][gy]<'A'||M[gx][gy]>'Z')&&
(f[nx][ny]==(i%2)||(g&(1<<tun[nx][ny]))))
que.push(g,gx,gy,ans[G][x][y]+1);
else continue;//有管道过不去
else que.push(g,nx,ny,ans[G][x][y]+1);
}
}
que.pop();
}
printf("10001");
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: