Maze
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5094
BFS+状态压缩
把身上携带钥匙的状态压缩成一个2^10的整数。这道题难在如何表示墙和门所在的位置,我是另开了个两个N*N的数组mp_r[N][N],mp_c[N][N]分别以行和列错位存储存储墙和门的位置(mp_r[i][j]表示第r行j列和第r行j+1列的墙的状态),而在其他人好像是用mp[N][N][4]来存储墙和门的状态的,突然觉得我好蠢...不过也有好处啦,空间大小比他们小好多,在hdu这题的statistic上排21哈哈。这题坑点是一个位置可以存多把钥匙(吐血 怪不得这么多次都是WA)= =
代码如下:
1 #include<cstdio> 2 #include<queue> 3 #include<cstring> 4 #define LL long long 5 #define N 55 6 using namespace std; 7 struct node{ 8 LL x,y,time; 9 bool key[10]; 10 }; 11 node s,e; 12 LL mp_r[N][N]; 13 LL mp_c[N][N]; 14 LL key[N][N][10]; 15 LL n,m,p; 16 bool mark[1024][N][N]; 17 bool flag; 18 LL dx[]={-1,1,0,0}; 19 LL dy[]={0,0,-1,1}; 20 LL zip(node t){ 21 LL code=0; 22 for(LL i=0;i<p;++i) 23 code=(code<<1)|t.key[i]; 24 return code; 25 } 26 void init(){ 27 flag=0; 28 s.x=1,s.y=1,s.time=0; 29 e.x=n,e.y=m,e.time=0; 30 memset(mp_r,-1,sizeof(mp_r)); 31 memset(mp_c,-1,sizeof(mp_c)); 32 memset(key,0,sizeof(key)); 33 memset(mark,0,sizeof(mark)); 34 mark[0][1][1]=1; 35 LL k; 36 scanf("%I64d",&k); 37 while(k--){ 38 LL x1,y1,x2,y2,g; 39 scanf("%I64d%I64d%I64d%I64d%I64d",&x1,&y1,&x2,&y2,&g); 40 if(x1-x2==0)mp_r[x1][(y1+y2)/2]=g; 41 else mp_c[(x1+x2)/2][y1]=g; 42 } 43 scanf("%I64d",&k); 44 while(k--){ 45 LL x,y,q; 46 scanf("%I64d%I64d%I64d",&x,&y,&q); 47 q--; 48 key[x][y][q]=1; 49 } 50 for(int i=0;i<10;i++) 51 if(key[1][1][i])s.key[i]=1; 52 } 53 int main(void){ 54 while(~scanf("%I64d%I64d%I64d",&n,&m,&p)){ 55 init(); 56 queue<node> que; 57 que.push(s); 58 while(!que.empty()){ 59 node t=que.front(); 60 que.pop(); 61 if(t.x==e.x&&t.y==e.y){ 62 e.time=t.time; 63 flag=1; 64 break; 65 } 66 for(LL i=0;i<4;++i){ 67 LL x=t.x+dx[i]; 68 LL y=t.y+dy[i]; 69 if(1<=x&&x<=n&&1<=y&&y<=m){ 70 node temp; 71 temp.x=x,temp.y=y,temp.time=t.time+1; 72 for(LL j=0;j<p;++j)temp.key[j]=t.key[j]; 73 for(int j=0;j<10;j++) 74 if(key[x][y][j])temp.key[j]=1; 75 if(dx[i]){ 76 if(mp_c[(x+t.x)/2][y]!=0) 77 if(mp_c[(x+t.x)/2][y]==-1||temp.key[mp_c[(x+t.x)/2][y]-1]){ 78 LL key_zip=zip(temp); 79 if(!mark[key_zip][x][y]){ 80 mark[key_zip][x][y]=1; 81 que.push(temp); 82 } 83 } 84 }else if(dy[i]){ 85 if(mp_r[x][(y+t.y)/2]!=0) 86 if(mp_r[x][(y+t.y)/2]==-1||temp.key[mp_r[x][(y+t.y)/2]-1]){ 87 LL key_zip=zip(temp); 88 if(!mark[key_zip][x][y]){ 89 mark[key_zip][x][y]=1; 90 que.push(temp); 91 } 92 } 93 } 94 } 95 } 96 } 97 if(flag)printf("%I64d\n",e.time); 98 else printf("-1\n"); 99 } 100 }
时间: 2024-10-13 00:23:07