您的位置:首页 > 其它

HDU 1728 逃离迷宫

2013-12-04 16:56 295 查看
一直wa,搜索真不愧是我的最大弱点。

剪枝判断没做好,加入队列条件也没有控制好

1.广搜省时间。。大神XX当时集训用深搜一次搞定了。。差距啊。。

2.每次搜都直接搜到底。

3.先标记一下今天惨烈错误的地方,有空将错误过程写上去

贴一下

#include <stdio.h>
#include <queue>
using namespace std;

#define maxn 101

int x1,x2,y1,y2,n,m,K;
int vis[maxn][maxn] , stp[maxn][maxn] , dir[maxn][maxn];

int tn , tx , ty , nx , ny , ts;
const int dx[] = {0,1,0,-1};
const int dy[] = {1,0,-1,0};
int maz[maxn+10][maxn+10];

bool is_ok(int x,int y){
return x>=0&&x<n&&y<m&&y>=0&&maz[x][y]=='.';
}

bool bfs(){
memset(vis, 0 , sizeof(vis));
queue<int> q;stp[x1][y1] = 0; K++;
q.push(x1*m+y1); vis[x1][y1] = 1; dir[x1][y1]=-1;
while(!q.empty()){
tn = q.front(); q.pop();
tx = tn / m , ty = tn % m;
if(stp[tx][ty] > K) continue;
if(stp[tx][ty] <= K && tx==x2&&ty==y2) return true;
for(int i=0;i<4;i++){
nx = tx + dx[i] , ny = ty + dy[i];
while(is_ok(nx,ny)){
if(vis[nx][ny]==0){
vis[nx][ny] = 1;
dir[nx][ny] = i;
if(dir[tx][ty]==i) stp[nx][ny]=stp[tx][ty];
else if(dir[tx][ty]==-1||dir[tx][ty]!=i)
stp[nx][ny] = stp[tx][ty]+1;
if(nx==x2&&ny==y2&&stp[nx][ny]<=K)
return true;
q.push(nx*m+ny);
}
nx += dx[i] , ny += dy[i];
}
}
}return false;
}

int main(){

int T;char ma[110];
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
memset(maz,0,sizeof(maz));
for(int i=0;i<n;i++){
scanf("%s",ma);
for(int j=0;j<m;j++) maz[i][j] = ma[j];
}
scanf("%d %d %d %d %d",&K,&y1,&x1,&y2,&x2);
y1--,x1--,y2--,x2--;
puts(bfs() ? "yes" : "no");
}
return 0;
}


View Code


S点是一个相遇的点,从路径c和路径f过来都是可以到达的,这里先不考虑转折的问题。每次搜索找沿每个方向找到最底

1.每次一次搜索到尽头的方法一定使得被搜索点一定最优,转折最少(两点间直线最短)

2.像S点,假设一种情景,沿f,c路径到达S点的转折数是一样的,而且c路径先到达,那么f路径经过该点如何处理?

3.由于S被搜索过了,但是,队列中S点还没有往上下方向移动,所以,应该继续搜索下去。PS:之前在S点停止搜索了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: