您的位置:首页 > 其它

hdu 1254 推箱子 广搜+ 深搜

2012-05-05 20:00 369 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1254

注意以下几点

1. 箱子是否可走

2. 人是否可达箱子后面

3. 箱子的每个方向只走一次,而不是每个位置

广搜箱子路径,深搜人可否达箱子后面, 记录方向用visb[10][10][4]来记录

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
using namespace std;
int a[10][10], m, n, sx, sy, px, py, visb[10][10][4], visp[10][10], flag;
int mov[4][2]= {1, 0, 0, 1, -1, 0, 0, -1};
struct node{
int x, y, px, py, step;
};
void init(){
int i, j;
scanf("%d%d", &m, &n);
for( i=0; i<m; i++)
for( j=0; j<n; j++){
scanf("%d", &a[i][j]);
if( a[i][j]==2) sx= i, sy= j;
if( a[i][j]==4) px= i, py= j;
}
memset( visb, 0, sizeof( visb));
}
bool check(int x, int y){
if( x>=0 && x<m && y>=0 && y<n && a[x][y]!= 1) return true;
return false;
}
bool dfs(int dx, int dy, node temp){
if( flag )return true;
int i, j;
node next;
if( dx== temp.px && temp.py== dy) {
flag= 1;
return true;
}
next.x= temp.x, next.y=temp.y;
for( i=0; i<4; i++){
next.px= temp.px + mov[i][0];
next.py= temp.py + mov[i][1];
//注意搜索人是否可达箱子后面时,不仅不可走1位置,也不能走箱子目前的位置
if( check( next.px, next.py) && !visp[next.px][next.py] && !( next.px == temp.x && next.py== temp.y)){
visp[ next.px][next.py]= 1;
if( dfs( dx, dy, next) ) return true;
visp[next.px][next.py]= 0; //回溯不要写在else里……………………
}
}
return false;
}
void bfs(){
int i, j, k, rx, ry;
queue<node >q;
node start, next, head;
start.px= px, start.py= py;
start.x= sx, start.y= sy;
start.step= 0;
q.push( start );
while( !q.empty()){
head= q.front();
q.pop();
if( a[head.x][head.y]== 3){
printf("%d\n", head.step);
return;
}
//cout<<head.x<<" "<<head.y<<endl;
for( i=0; i<4; i++){
next.x= head.x+mov[i][0];  //箱子的目的地址
next.y= head.y+mov[i][1];
next.px= head.x;  //推箱子后人的位置为箱子所在位置
next.py= head.y;
next.step= head.step + 1;
rx= head.x- mov[i][0];  //箱子后面,人推箱子时所站的位置
ry= head.y- mov[i][1];
if( check( next.x, next.y ) && !visb[next.x][next.y][i] && check( rx, ry)){
memset( visp, 0, sizeof( visp));
visp[head.px][head.py]= 1;
flag= 0;
if( dfs( rx, ry, head) ){  //看人是否可达箱子后面
visb[ next.x][next.y][i]= 1;
q.push( next);
//cout<<next.x<<" "<<next.y<<" "<<next.px<<" "<<next.py<<endl;
}

}
}
}
printf("-1\n");
}
int main(){
//  freopen("1.txt", "r", stdin);
int T;
scanf("%d", &T);
while( T--){
init();
bfs();
}
return 0;
}


第一次深搜时,搜索到了忘记return了……效率好低
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: