DFS:Curling 2.0(POJ 3009)

              

                  冰壶2.0

  题目大意:就是给你一个冰壶和一个地图,地图上有石头,冰壶只能沿着x方向和y方向运动,并且要一直运动直到撞到石头为止,并且沿着此方向撞过来会把挡住的石头撞没,冰壶在停的时候可以扔出去一次,最多只能扔10次,问你冰壶能否到指定点?

  这一题原题非常长,需要很细心地读题(比如我一开始的时候就是没看到只能扔10次,导致好几次tle),而且这一题一开始我还做复杂了,一开始的时候用的是dfs+dp去储存最短距离,可是我发现冰壶会撞烂石头,所以储存最短距离是不行的,所以只能直接dfs了

  直接dfs的方法就是沿着一个方向,如果没有障碍物,我们就继续往下一个搜索,如果遇到障碍物,那么我们就在这个方向再沿着4个方向再搜索(如果没有石头挡着的话),遇到终点我们就更新minstep,如果扔的次数大于10次,那么就不用再搜索了,minstep初始化为11就好了

  PS:这一题一开始我是256ms过的(因为我用的INT_MAX返回来标记的,非常耗时间),后来删掉了返回值,直接用step标记,速度直接快了一倍,然后还更简洁了

    另外WA好几次,还是边界判断的问题,看来我还是要多注意一下

                  

  

  1 #include <iostream>       
  2 #include <algorithm>
  3 
  4 using namespace std;
  5 typedef int Direction;//0表示左,1表示右,2表示上,3表示下
  6 typedef int Position;
  7 
  8 static int  w, h;
  9 static int map[20][20];//0联通,1阻挡,2起点,3终点
 10 static pair< int, int >start;
 11 static pair< int, int >goal;
 12 int minstep;
 13 
 14 void Search(const Position, const Position, const Direction, const int);
 15 void Find_Ans(Position, Position, Direction, const int);
 16 void Read_Map(const int,const int);
 17 
 18 int main(void)
 19 {
 20     while (~scanf("%d%d", &w, &h))
 21     {
 22         if (w == 0 && h == 0)
 23             break;
 24         Read_Map(h, w);
 25         minstep = 11;
 26         for (int i = 0; i < 4; i++)
 27         {
 28             if (i == 0 && start.second - 1 >= 0 && map[start.first][start.second - 1] != 1)
 29                 Search(start.first, start.second, i, 1);
 30             else if (i == 1 && start.second + 1 < w && map[start.first][start.second + 1] != 1)
 31                 Search(start.first, start.second, i, 1);
 32             else if (i == 2 && start.first - 1 >= 0 && map[start.first - 1][start.second] != 1)
 33                 Search(start.first, start.second, i, 1);
 34             else if (i == 3 && start.first + 1 < h && map[start.first + 1][start.second] != 1)
 35                 Search(start.first, start.second, i, 1);
 36         }
 37         if (minstep > 10)
 38             cout << -1 << endl;
 39         else
 40             cout << minstep << endl;
 41     }
 42     return 0;
 43 }
 44 
 45 void Read_Map(const int h, const int w)
 46 {
 47     for (int y = 0; y < h; y++)
 48     {
 49         for (int x = 0; x < w; x++)
 50         {
 51             scanf("%d", &map[y][x]);
 52             if (map[y][x] == 2)
 53             {
 54                 start.first = y;//y坐标
 55                 start.second = x;//x坐标
 56             }
 57             if (map[y][x] == 3)
 58             {
 59                 goal.first = y;//y坐标
 60                 goal.second = x;//x坐标
 61             }
 62         }
 63     }
 64 }
 65 
 66 void Find_Ans(Position y, Position x, Direction dir,const int step)
 67 {
 68     for (int i = 0; i < 4; i++)
 69     {
 70         if (i == 0 && x - 1 >= 0 && map[y][x - 1] != 1)
 71             Search(y, x - 1, i, step + 1);
 72         else if (i == 1 && x + 1 < w && map[y][x + 1] != 1)
 73             Search(y, x + 1, i, step + 1);
 74         else if (i == 2 && y - 1 >= 0 && map[y - 1][x] != 1)
 75             Search(y - 1, x, i, step + 1);
 76         else if (i == 3 && y + 1 < h && map[y + 1][x] != 1)
 77             Search(y + 1, x, i, step + 1);
 78     }
 79 }
 80 
 81 void Search(const Position y, const Position x, const Direction dir,const int step)
 82 {
 83     if (step > minstep)
 84         return;
 85     if (x == goal.second && y == goal.first)//如果这个点就是正确的点,返回0步
 86     {
 87         minstep = min(minstep, step);
 88         return;
 89     }
 90     if (dir == 0)
 91     {
 92         if (x - 1 < 0)
 93             return;
 94         else if (map[y][x - 1] != 1)
 95             Search(y, x - 1, dir, step);
 96         else
 97         {
 98             map[y][x - 1] = 0;//先撞烂
 99             Find_Ans(y, x, dir, step);
100             map[y][x - 1] = 1;//然后补回来
101         }
102     }
103     else if (dir == 1)
104     {
105         if (x + 1 >= w)
106             return;
107         else if (map[y][x + 1] != 1)
108             Search(y, x + 1, dir, step);
109         else
110         {
111             map[y][x + 1] = 0;//先撞烂
112             Find_Ans(y, x, dir, step);
113             map[y][x + 1] = 1;//然后补回来
114         }
115     }
116     else if (dir == 2)
117     {
118         if (y - 1 < 0)
119             return;
120         else if (map[y - 1][x] != 1)
121             return Search(y - 1, x, dir, step);
122         else
123         {
124             map[y - 1][x] = 0;//先撞烂
125             Find_Ans(y, x, dir, step);
126             map[y - 1][x] = 1;//然后补回来
127         }
128     }
129     else
130     {
131         if (y + 1 >= h)
132             return;
133         else if (map[y + 1][x] != 1)
134             Search(y + 1, x, dir, step);
135         else
136         {
137             map[y + 1][x] = 0;//先撞烂
138             Find_Ans(y, x, dir, step);
139             map[y + 1][x] = 1;//然后补回来
140         }
141     }
142 }
原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/4842165.html