HDU 1728 逃离迷宫【BFS】

题意:给出一个起点,一个终点,规定的转弯次数,问能否在规定的转弯次数内到达终点---

这一题是学(看)习(题)的(解)@_@

主要学了两个地方

一个是剪枝,如果搜到的当前点的转弯次数小于该点turn数组记录下来的转弯次数,才有必要将它加入队列。

另一个是记录转弯方向 在结构体里面定义一个turn来记录转弯的个数,用dir来记录当前所在的方向(因为搜的时候是四个方向dir[4][2]来搜的,直接用i确定当前方向即可)

想想自己第一次做的时候的doubi想法,用dfs做,然后dfs(x,y,px,py),再判断由(x+dir[i][0],y+dir[i][1])与(x,y)构成的直线斜率和(x,y)和(px,py)构成的斜率乘积是否为-1-----果断没有写对----

 1 #include<iostream>  
 2 #include<cstdio>  
 3 #include<cstring>  
 4 #include<algorithm> 
 5 #include<queue> 
 6 using namespace std;
 7 int turn[105][105];
 8 int n,m,k;
 9 int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
10 char map[105][105];
11 struct node
12 {
13     int x,y;
14     int turn,dir;//用turn来记录转弯的个数,用dir来记录当前的方向 
15 } st,en,now,next;
16 queue<node>q;
17 void bfs()
18 {
19     while(!q.empty()) q.pop();
20     now.x=st.x;now.y=st.y;now.dir=-5;now.turn=0;//初始的方向可以定义为任意一个后来不会出现的方向 
21     turn[now.x][now.y]=0;    //在起点时可以转向任意方向,令为0 
22     q.push(now);
23     while(!q.empty())
24     {
25         now=q.front();q.pop();
26     
27         for(int i=0;i<4;i++)
28         {
29             next.x=now.x+dir[i][0];
30             next.y=now.y+dir[i][1];
31             next.dir=now.dir;
32             next.turn=now.turn;
33             if(now.x==en.x&&now.y==en.y&&now.turn<=k)
34             {
35             printf("yes\n");
36             return;            
37             }
38             if(next.x<1||next.x>m||next.y<1||next.y>n||map[next.x][next.y]=='*') continue;//第一次剪枝 
39             if(next.dir!=i&&next.dir!=-5) //如果当前方向和起始不同,则turn++ 
40                 next.turn++;
41             if(next.turn>k) continue;//第二次剪 枝,转弯次数超过了,则剪枝 
42             if(next.x==en.x&&next.y==en.y&&next.turn<=k)
43             {
44             printf("yes\n");
45             return;            
46             }
47             
48             if(next.turn<=turn[next.x][next.y])//第三次剪枝,如果当前转弯的个数小于当前点的转弯个数,才有继续搜索的必要 
49             {
50                 next.dir=i;
51                 turn[next.x][next.y]=next.turn;
52                 q.push(next);
53             }            
54         }
55     }
56     printf("no\n");
57     return;    
58 }
59 int main()
60 {
61     int ncase,i,j;
62     scanf("%d",&ncase);
63     while(ncase--)
64     {
65         scanf("%d %d",&m,&n);
66         for(i=1;i<=m;i++)
67         for(j=1;j<=n;j++)
68         {
69             cin>>map[i][j];
70             turn[i][j]=1000000;//初始化 每一点的转弯个数为一个极大的值 
71         }
72         cin>>k>>st.y>>st.x>>en.y>>en.x;
73         bfs();
74     }    
75 }
View Code

 

posted @ 2015-02-18 14:02  sequenceaa  阅读(140)  评论(0编辑  收藏  举报