zoukankan      html  css  js  c++  java
  • codeforces 793B

    题目链接: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
    ");
    53     else
    54         printf("NO
    ");
    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
    ",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
    ");
    75     else
    76         printf("NO
    ");
    77 } 
  • 相关阅读:
    算法作业实验三
    牛客练习赛53 B 美味果冻
    牛客练习赛53 C 富豪凯匹配串
    bitmat
    牛客挑战赛33 B 鸽天的放鸽序列
    树状数组
    线段树
    2019牛客国庆集训派对day7 A 2016
    背包
    作业三 -并查集
  • 原文地址:https://www.cnblogs.com/fu3638/p/6759919.html
Copyright © 2011-2022 走看看