hdu~1885(bfs+状态压缩)
来源:互联网 发布:网络大电影2016排行榜 编辑:程序博客网 时间:2024/05/17 02:11
Key Task
一开始用dfs果断超时,贴上超时代码:
<span style="font-size:18px;">#include <stdio.h>#include <iostream>#include <string.h>#define MAX 0xffffffint m,n,flag,tt,sx,sy;char key[]={'y','g','r','b'};char door[]={'Y','G','R','B'};int dirx[]={0,1,0,-1},diry[]={1,0,-1,0};char maze[105][105];bool mark[105][105][22];void dfs(int x,int y,int t,int k){ if(flag) return ; if(maze[x][y]=='X') { tt=t; flag=1; return ; } if(x<0 || x>=n || y<0 || y>=m || maze[x][y]=='#' || mark[x][y][k]) return ; if(isupper(maze[x][y]) && maze[x][y]!='X') //це { for(int i=0;i<=4;i++) if(maze[x][y]==door[i]) { if((k&(1<<i))==0) return ; } } else if(islower(maze[x][y])) //т©Ёв { for(int i=0;i<=4;i++) if(maze[x][y]==key[i]) { k|=(1<<i); break; } } for(int i=0;i<4;i++) { int fx=x+dirx[i]; int fy=y+diry[i]; mark[x][y][k]=true; dfs(fx,fy,t+1,k); mark[x][y][k]=false; }}int main(){ while(scanf("%d %d",&n,&m) &&(m || n)) { memset(mark,0,sizeof(mark)); flag=0; tt=-1; for(int i=0;i<n;i++) { scanf("%s",maze[i]); for(int j=0;j<m;j++) if(maze[i][j]=='*') sx=i,sy=j; } dfs(sx,sy,0,0); if(tt!=-1) printf("Escape possible in %d steps.\n",tt); else printf("The poor student is trapped!\n"); } return 0;}</span>
bfs+状态压缩
这题和普通的迷宫不一样的是多了4种钥匙以及对应的门
开一个三维数组mark[x][y][k]用来存各个位置的各种状态,通俗的说就是,判断在"k"这种状态下,x,y这个位置是否走过。
用二进制存得到钥匙的状态,用4位即可。
上代码:
#include <iostream>#include <stdio.h>#include <string.h>#include <queue>using namespace std;typedef struct ac{ int x,y,t; int k; //用二进制存4把钥匙}node;int dirx[]={0,1,0,-1},diry[]={1,0,-1,0}; bool mark[105][105][20]; //判断在有不同的key的各个位置是否出现过int m,n;char key[]={'b','g','y','r'};char door[]={'B','G','Y','R'};char maze[105][105]; void bfs(node s){ queue <node> q; mark[s.x][s.y][s.k]=true; q.push(s); while(!q.empty()) { node r=q.front(); q.pop(); if(maze[r.x][r.y]=='X') { printf("Escape possible in %d steps.\n",r.t); return ; } for(int i=0;i<4;i++) { node w=r; w.x+=dirx[i]; w.y+=diry[i]; w.t++; if(w.x<0 || w.x>=n || w.y<0 || w.y>=m || maze[w.x][w.y]=='#')//撞墙 continue ; if(isupper(maze[w.x][w.y]) && maze[w.x][w.y]!='X') //door { for(int i=0;i<4;i++) { //找到对应的门,且有该门的钥匙,且在这种状态下的这个位置未走过 if(maze[w.x][w.y]==door[i] && (w.k & (1<<i)) && (!mark[w.x][w.y][w.k])) { mark[w.x][w.y][w.k]=true; q.push(w); } } } else if(islower(maze[w.x][w.y])) //key { for(int i=0;i<4;i++) { if(maze[w.x][w.y]==key[i]) { w.k|=(1<<i); //key记录得到这把钥匙 if(!mark[w.x][w.y][w.k]) { mark[w.x][w.y][w.k]=true; q.push(w); } } } } else if(!mark[w.x][w.y][w.k]) //普通的路 { mark[w.x][w.y][w.k]=true; q.push(w); } } } printf("The poor student is trapped!\n");}int main(){ while(scanf("%d %d",&n,&m) && (m ||n)) { node s; memset(mark,0,sizeof(mark)); for(int i=0;i<n;i++) { scanf("%s",maze[i]); for(int j=0;j<m;j++) if(maze[i][j]=='*') s.x=i,s.y=j; } s.k=0; s.t=0; bfs(s); } return 0;}
0 0
- hdu 1885(状态压缩+bfs)
- HDU 1885 BFS+状态压缩
- hdu~1885(bfs+状态压缩)
- BFS+状态压缩 hdu-1885-Key Task
- HDU 1885Key Task(bfs + 状态压缩)
- hdu 1885 Key Task bfs + 状态压缩
- Hdu-1885-Key Task [状态压缩][bfs]
- HDU 1885 Key Task 状态压缩+BFS
- hdu 1429 BFS+状态压缩
- hdu 2209 BFS + 状态压缩
- HDU 4634 - BFS + 状态压缩
- hdu 4012 状态压缩BFS
- HDU 4771 BFS+状态压缩
- HDU 1429 BFS+状态压缩
- hdu~1429(bfs+状态压缩)
- HDU 1429 BFS+状态压缩
- hdu 1429 bfs+状态压缩
- hdu~5025(bfs+状态压缩)
- 找出一个个既有正数又有负数的数组中子数组的和的最大值
- java基础-多态篇
- 数组元素两两比较重复值
- 第6周项目5——友元类
- hook虚表监控虚表
- hdu~1885(bfs+状态压缩)
- 我的数组类
- svg绘制曲线
- log4j.properties配置详解(转载)
- jsp----学习-----Servet 01
- java 微信获取accessToken
- 第六周上机实践项目6-复数模板类(1类外定义、2加减乘除)
- Xcode 6 正式版如何创建一个Empty Application
- Java、android开发环境变量的配置