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 */