codeforces 793B - Igor and his way to work(dfs、bfs)

题目链接:http://codeforces.com/problemset/problem/793/B

题目大意:告诉你起点和终点,要求你在只能转弯两次的情况下能不能到达终点。能就输出“YES”,不能就输出“NO”。

解题思路:这算是经典的转弯题了,接近半年没写搜索题了,,所以今天先拿这道题开刀吧。这个题关键就是“判重”,如何记录走过的点。我们可以开个三维数组,记录各个坐标各个方向上的转弯数,如果下次在到这个点这个方向,那就比较转弯数,如果这次转弯数大于等于已经记录的转弯数那就不用再找下去了,因为这次能走到的地方,上次肯定也能走到。估计一下时间复杂度大概为O(4*3n)。

dfs:

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 const int N=1e3+5;
 5 int m,n;
 6 bool flag=false;
 7 char map[N][N];
 8 int vis[N][N][5];//*关键*用来标记走过的点,记录该点朝着各方向转弯数 
 9 int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
10 
11 void dfs(int x,int y,int dir,int cnt){
12     if(x<=0||x>m||y<=0||y>n||cnt>2)
13         return;    
14     if(vis[x][y][dir]<=cnt)//如果这个位置这个方向已经走过,且用了更小的转弯数,那就不用再走这个点了
15         return;
16     if(map[x][y]=='T'){
17         flag=true;
18         return;
19     }    
20     if(map[x][y]!='.'&&map[x][y]!='S')
21         return;
22     vis[x][y][dir]=cnt;
23     for(int i=0;i<4;i++) {
24         int x1=x+d[i][0];
25         int y1=y+d[i][1];
26         if(dir==-1)
27             dfs(x1,y1,i,cnt);
28         else if(dir!=i)
29             dfs(x1,y1,i,cnt+1);
30         else
31             dfs(x1,y1,i,cnt);
32     }
33 }
34 
35 int main(){
36     int index,indey;
37     scanf("%d %d",&m,&n);
38     getchar();
39     for(int i=1;i<=m;i++){
40         for(int j=1;j<=n;j++){
41             scanf("%c",&map[i][j]);
42             if(map[i][j]=='S'){
43                 index=i;
44                 indey=j;
45             }
46         }
47         getchar();
48     }
49     memset(vis,0x3f,sizeof(vis));//转弯数初始化为无限大 
50     dfs(index,indey,-1,0);//-1表示开始位置没有方向
51     if(flag)
52         printf("YES\n");
53     else
54         printf("NO\n");
55 }

bfs,跟上面差不多的:

 1 #include<iostream>
 2 #include<cstring>
 3 #include<queue>
 4 using namespace std;
 5 const int N=1e3+5;
 6 int vis[N][N][5];
 7 int d[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
 8 char map[N][N];
 9 int m,n;
10 bool flag=false;
11 
12 struct node{
13     int x,y,dir,cnt;
14 }now,t,pre;
15 //int num=0;
16 void bfs(int stax,int stay){
17     queue<node>q;
18     t.x=stax;
19     t.y=stay;
20     t.dir=-1;
21     t.cnt=0;
22     q.push(t);
23     while(!q.empty()){
24         pre=q.front();
25         q.pop();
26         for(int i=0;i<4;i++){
27             int x=pre.x+d[i][0];
28             int y=pre.y+d[i][1];
29             int cnt;
30             if(pre.dir==-1)//判断一下上次方向和当前要走的方向的关系 
31                 cnt=0;
32             else if(pre.dir==i)
33                 cnt=pre.cnt;
34             else if(pre.dir!=i)
35                 cnt=pre.cnt+1;
36             if(x<=0||x>m||y<=0||y>n||cnt>2)
37                 continue;
38             if(map[x][y]=='T'){//到达终点 
39                 flag=true;
40                 return;
41             }
42             if(map[x][y]!='S'&&map[x][y]!='.')
43                 continue;
44             if(vis[x][y][i]<=cnt)//这个点这个方向已经有更优方案了 
45                 continue;
46             vis[x][y][i]=cnt;
47             now.x=x;
48             now.y=y;
49             now.dir=i;
50             now.cnt=cnt;
51 //            num++;
52 //            printf("%d\n",num);
53             q.push(now);
54         }    
55     }
56 }
57 int main(){
58     int index,indey;
59     scanf("%d %d",&m,&n);
60     getchar();
61     for(int i=1;i<=m;i++){
62         for(int j=1;j<=n;j++){
63             scanf("%c",&map[i][j]);
64             if(map[i][j]=='S'){
65                 index=i;
66                 indey=j;
67             }
68         }
69         getchar();
70     }
71     memset(vis,0x3f,sizeof(vis));
72     bfs(index,indey);
73     if(flag)
74         printf("YES\n");
75     else
76         printf("NO\n");
77 } 

 

posted @ 2017-04-25 00:11  Yeader  阅读(759)  评论(1编辑  收藏  举报