深搜递归回来时候,取消与不取消标记的探讨

 1 #define _CRT_SECURE_NO_WARNINGS  
 2 #include <stdio.h>
 3 #include <math.h>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 #include <vector>
 7 #include <map>
 8 #include <queue>
 9 #include <string>
10 #include <iostream>
11 #include <ctype.h>
12 #include <string.h>
13 #include <set>
14 #include <stack>
15 #include<functional>
16 using namespace std;
17 #define Size 22
18 #define maxn  1<<30
19 #define minn  1e-6
20 char a[Size][Size];
21 int mark[Size][Size];
22 int stx, sty;
23 int width, len;
24 int ans;
25 int go[4][2] = { 0, 1, 1, 0, 0, -1, -1, 0 };
26 void solve(int x,int y,int step){
27     if (x<1 || y<1 || x>len || y>width||a[x][y]=='#'){
28         if (ans < step){
29             cout << step << endl;
30             ans = step;
31         }
32     }
33     else {
34         for (int i = 0; i < 4; i++){
35             int tx = x + go[i][0];
36             int ty = y + go[i][1];
37             if (mark[tx][ty])  continue;
38             if (a[tx][ty] == '.') step++;
39             mark[tx][ty] = 1;
40             solve(tx, ty,step);
41             mark[tx][ty] = 0;//所以不标记的情况一般是在重复使用字母,数字的时候,解空间很小的情况下,如果要搜索地图的时候,不标记,时间太多不可接受
42             /*
43             虽然可能搜索到最终答案但是,解空间是非常大的如果不标记的话那么,因为除过此来到的路其他路都要再走一次,解空间非常大非常大可能是3^64
44         因为其等于计算了从起点到地图上任意一点的所有路径,假设每次有三个选择,那么在一个8*8的地图上那么总共要计算的次数是64*3^64,天文数字

               而不取消标记的情况是计算,即深搜的模板方案,是计算最佳方案的即为,计算最快到达i,j点的路径,要计算最慢到达ij的路径就不行了,此题等效计算最长路径
45             */
46             if (a[tx][ty] == '.') step--;
47         }
48     }
49 }
50 
51 int main(){
52 
53     while (cin >> width >> len){
54         int num = 0;
55         for (int i = 1; i <= len; i++)
56             for (int j = 1; j <= width; j++){
57                 mark[i][j] = 0;
58                 cin >> a[i][j];
59                 if (a[i][j] == '@') stx = i, sty = j;
60             }
61         mark[stx][sty] = 1;
62         ans = 0;
63         solve(stx, sty,1);//将要探索stx,sty,以及走了0步了
64     }
65     return 0;
66 }
 

 

 1 #define _CRT_SECURE_NO_WARNINGS  
 2 #include <stdio.h>
 3 #include <math.h>
 4 #include <algorithm>
 5 #include <stdlib.h>
 6 #include <vector>
 7 #include <map>
 8 #include <queue>
 9 #include <string>
10 #include <iostream>
11 #include <ctype.h>
12 #include <string.h>
13 #include <set>
14 #include <stack>
15 #include<functional>
16 using namespace std;
17 #define Size 78
18 #define maxn  1<<30
19 #define minn  1e-6
20 char  a[Size][Size];
21 int mark[Size][Size];
22 int width, len;
23 int stx, sty, edx, edy;
24 int ans;
25 /*
26 当x2,y2在x1,y1的左上角时,他首选的路线是上和左,其次才是右和下;其它方向同理
27 mark 标记
28 递归
29 mark 标记去除
30 
31 这种递归的找所有解的方案,方向的选取就起着决定性的作用
32 
33 int go[4][2] = { { 0, -1 }, { 0, 1 }, { 1, 0 }, { -1, 0 } }; 超时
34 int go[4][2]={{0,1},{1,0},{0,-1},{-1,0}};就过了
35 */
36 int go[4][2] = { { 0, -1 }, { 0, 1 }, { 1, 0 }, { -1, 0 } };
37 void solve(int x, int y, int step, int direction){
38     if (step > ans) return;
39     if (x == edx&&y == edy){
40         ans = step;
41         return;
42     }
43     for (int i = 0; i < 4; i++){
44         int tx = x + go[i][0];
45         int ty = y + go[i][1];
46         if (tx<0 || ty<0 || tx>len+1 || ty>width+1) continue;
47         if (mark[tx][ty] == 1) continue;
48         if (a[tx][ty] == ' ' || a[tx][ty] == 'X'&&tx == edx&ty == edy){
49             mark[tx][ty] = 1;
50             if (direction == i) solve(tx, ty, step, i);
51             else solve(tx, ty, step + 1, i);
52             mark[tx][ty] = 0;
53         }
54     }
55 }
56 int main(){
57     int b = 1;
58     while (scanf("%d%d",&width,&len)==2){
59         if (width == 0&&len==0) break;
60         for (int i = 0; i<77; i++)
61             a[i][0] = a[0][i] = ' ';
62         for (int i = 1; i<len + 1; i++){
63             getchar();
64             for (int j = 1; j<width + 1; j++)
65                 a[i][j] = getchar();
66         }
67         for (int i = 0; i<width + 1; i++)
68             a[len + 1][i + 1] = ' ';
69         for (int i = 0; i<len + 1; i++)
70             a[i + 1][width + 1] = ' ';
71 
72         int Case = 1;
73         printf("Board #%d:\n", b++);
74         while (scanf("%d%d%d%d",&sty,&stx,&edy,&edx)==4){
75             if (sty == 0) break;
76             memset(mark, 0, sizeof(mark));
77             ans = 9999;
78             solve(stx, sty, 0, -1);
79             if (ans == 9999) printf("Pair %d: impossible.\n", Case);
80             else
81                 printf("Pair %d: %d segments.\n", Case, ans);
82             Case++;
83         }
84         cout << endl;
85     }
86     return 0;
87 }

 

posted @ 2018-01-28 22:18  MapReduce  阅读(221)  评论(0编辑  收藏  举报