hdu上的这道题可把我给坑惨了,一直都是runtime error,思想我感觉没错,可惜一直找不到原因。。。。
好吧,看的我眼都快花了,直接贴代码了,bfs+位压缩。。。
所谓的位压缩就是用一个整数来保存几个事物的有无状态。我们知道每个整数对应一个二进制,二进制就是01串,而0对应的就是无,1对应有,这样几个事物的有无就可以确定一个二进制串,进而可以确定一个整数。故用整数保存几个事物的有无状态。假设已知一个整数m,要判断事物n(n是编号,从1开始)是否存在,可以进行&运算:m&1<<n-1,如果运算结果为0,则n不存在,如果运算结果非0,则n已存在。如果n不存在,要把n加入,可以进行 | 运算:m | 1<<n-1,可以用运算结果来记录这个新状态。
下面的代码在杭电上的结果是runtime error
还请大神看看,哪儿出错了。。。orz
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<queue> 5 using namespace std; 6 7 int n,m,time; 8 int visited[25][25][1025];//共10把钥匙,共有1024中状态 9 char map[25][25]; 10 int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};//下、上、左、右 11 int sx,sy,ex,ey; 12 13 struct point { 14 int x,y; 15 int time; 16 int key;//标记当前找到钥匙的状态 17 }; 18 19 void bfs(int x,int y){ 20 queue<point>Q; 21 point s; 22 s.x=x,s.y=y,s.time=0,s.key=0; 23 Q.push(s); 24 visited[s.x][s.y][s.key]=1; 25 while(!Q.empty()){ 26 point p; 27 p=Q.front(); 28 Q.pop(); 29 if(p.x==ex&&p.y==ey&&p.time<time){ 30 printf("%d\n",p.time); 31 return ; 32 } 33 for(int i=0;i<4;i++){ 34 point q; 35 q.x=p.x+dir[i][0]; 36 q.y=p.y+dir[i][1]; 37 q.time=p.time+1; 38 q.key=p.key; 39 if(visited[q.x][q.y][q.key]||map[q.x][q.y]=='*') 40 continue; 41 if(q.x>=n||q.x<0||q.y>=m||q.y<0||q.time>=time) 42 continue; 43 else if(map[q.x][q.y]>='A'&&map[q.x][q.y]<='J'){ 44 int key=(q.key>>(map[q.x][q.y]-'A'));//找寻对应钥匙的位置 45 //如果存在该钥匙 46 if(key&1){ 47 Q.push(q); 48 } 49 visited[q.x][q.y][q.key]=1; 50 }else if(map[q.x][q.y]>='a'&&map[q.x][q.y]<='j'){ 51 visited[q.x][q.y][q.key]=1; 52 q.key|=(1<<(map[q.x][q.y]-'a'));//加入钥匙 53 visited[q.x][q.y][q.key]=1; 54 Q.push(q); 55 }else { 56 visited[q.x][q.y][q.key]=1; 57 Q.push(q); 58 } 59 } 60 } 61 printf("-1\n"); 62 } 63 64 int main(){ 65 while(scanf("%d%d%d",&n,&m,&time)!=EOF){ 66 for(int i=0;i<n;i++){ 67 scanf("%s",map[i]); 68 for(int j=0;j<m;j++){ 69 if(map[i][j]=='@'){ 70 sx=i,sy=j; 71 map[i][j]='.'; 72 }else if(map[i][j]=='^'){ 73 ex=i,ey=j; 74 map[i][j]='.'; 75 } 76 } 77 } 78 memset(visited,0,sizeof(visited)); 79 bfs(sx,sy); 80 } 81 return 0; 82 }