Fork me on GitHub

poj3984

  3/24考完蓝桥杯只做出了1个编程题,4个填空题,能不能省一还不知道,本来是想为了明年二战准备的,希望复试可以多一点加成。

最后一个填空题没有做出来,题目是给你30*50的地图(0/1组成),从(0,0)到(29,49)找出一条最短的路径并且输出路径(按照字典序)。当时没有调试出来,回到学校找到了poj的类似题目a掉了

 

题目链接:http://poj.org/problem?id=3984

题目大意:给你5*5的地图,上下左右,从左上角走到右下角,找出最短路径并且输出这条路径

 

绕了很多弯路,最后总算自己想出来了,很久不摸bds,不看题解,能自己想出来ac还是有点激动的

总结:出错原因

0.要用队列,设一个变量指向头一个指向尾巴

1.走过的要标注不再走了,之前想的是我地图里总有可以到达(4,4)的一条路径,我不用标注到终点了直接break就行,但是实际打印了一下发现不标注会走很多次,很久才到终点,甚至没到终点就return 负数自动结束了,猜测可能爆队列还是什么的

2.我最短路径每次++不知道放在哪里,之前放在了for(0~5)这里,觉得只要for一次就要++,因为以我这个点为中心其他上下左右都要一次入队列,就想for之后++可以记录最短,但是没有想到的是,这是广搜,搜到会跳出打印最短步数,走到非最短路径的那些点去for结束++的时候就多加了步数。正确的记录步数++应该是开一个二维数组,我在上一步的基础上+1,单独计算步数,不会出错。

(观众:你能说点人话嘛,表示听不懂~)

 

以上是考场犯下的错误QAQ~

下面是回到寝室想了一下午想出来的如何记录路径:

我用一个二维数组的结构体(成员为parentX, parentY),每一次记录下他的父亲和上下左右四个(最多)儿子的关系,最后倒着输出从(4,4)往回找

 

注意:

1 t = trackfirst[m][n].parentX;
2 n = trackfirst[m][n].parentY;
3 m = t;

这里之前写的是

1 m = trackfirst[m][n].parentX;
2 n = trackfirst[m][n].parentY;

找了好久Orz,被保研室友lbc回来秒看出错误。

这里结构体设置的收获是看谁多,多的开数组记录,少的作为成员变量,比如这里是儿子多,父亲少,一个父亲对0-4个儿子,所以用数组来存储儿子,用双亲parentX, parentY代表成员。

 

好了重新理一下思路:

好想没什么好说的~

 

PS:用的是队列并且一定要加入标志判断,走过的就不要再走了

草稿代码(ac):

  1 #include<cstdio>
  2 #include<cstring>
  3 struct trackfirst
  4 {
  5     int parentX;
  6     int parentY;
  7 }trackfirst[5][5];//, mmaapp[100000];
  8 
  9 struct d
 10 {
 11     int x;
 12     int y;
 13 }mmaapp[1000000];
 14 int main()
 15 {
 16 
 17     freopen("C:\\Users\\GerJCS岛\\Desktop\\t.txt", "r", stdin);
 18  int minspace;
 19     for(int i = 0; i < 5; i ++)
 20         for(int j = 0; j < 5; j ++){
 21             trackfirst[i][j].parentX = -1;
 22             trackfirst[i][j].parentY = -1;
 23         }
 24     int pose[5][5];
 25 //    int trackfirst;//25个父亲,每个父亲最多5个儿子   //[25][25][25];
 26     int save[500][500];
 27     int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
 28     int map[5][5];
 29     int queue[500][500];
 30     memset(save, 0, sizeof(save));
 31     memset(pose, 0, sizeof(pose));
 32     for(int i = 0; i < 5; i ++){
 33         for(int j = 0; j < 5; j ++)
 34             scanf("%d", &map[i][j]);
 35 //        getchar();
 36     }
 37 //    for(int i = 0; i < 5; i ++)
 38 //    {
 39 //        for(int j = 0; j < 5; j ++)
 40 //            printf("%c", map[i][j]);
 41 //        printf("\n");
 42 //    }
 43     int x, y;
 44     int x1, y1;
 45     int q = 0;
 46     int pflag = 0;
 47     queue[q][0] = 0;
 48     queue[q ++][1] = 0;
 49     save[0][0] = 1;
 50     pose[0][0] = 1;
 51     while(pflag <= q)
 52     {
 53 //        q --;
 54         x = queue[pflag][0];
 55         y = queue[pflag][1];
 56 
 57 //        if(x == 4 && y == 4){
 58 //            printf("%d\n", pose[x][y]);
 59 //            break;
 60 //        }
 61 //        printf("TEST\n");
 62         int wp = 0;
 63         for(int i = 0; i < 4; i ++){
 64             x1 = x + dir[i][0];
 65             y1 = y + dir[i][1];
 66             if(x1 >= 0 && x1 < 5 && y1 >= 0 && y1 < 5 && map[x1][y1] == 0 && !save[x1][y1]){
 67                 queue[q][0] = x1;
 68                 queue[q++][1] = y1;
 69                 save[x1][y1] = 1;
 70                 pose[x1][y1] = pose[x][y] + 1;
 71 
 72                 if(i != 0){//上一次直接用数组,造成了重复赋值
 73                     trackfirst[x1][y1].parentX = x;
 74                     trackfirst[x1][y1].parentY = y;
 75                 }
 76 
 77                 if(x1 == 4 && y1 == 4){
 78 //                    printf("#%d#, %d %d %d\n", pose[x1][y1], wp, x, y);
 79 //                    printf("#%d#\n", pose[x1][y1]);
 80                     minspace = pose[x1][y1];
 81                     break;
 82                 }
 83 //                printf("***%d **\n", pose[x1][y1]);
 84             }
 85         }
 86 //        ans ++;
 87         pflag ++;
 88     }
 89     int m = 4;
 90     int n = 4;
 91 
 92    /*
 93     printf("(4, 4)\n");
 94 //    printf("(2, 4)的父亲是:%d %d\n", trackfirst[2][4].parentX, trackfirst[2][4].parentY);
 95 //    printf("(0, 0)的父亲是:%d %d\n", trackfirst[0][0].parentX, trackfirst[0][0].parentY);
 96 ////    while(trackfirst[m][n].parentX != -1 && trackfirst[m][n].parentY != -1){
 97     while(1){
 98         printf("(%d, %d)\n", trackfirst[m][n].parentX, trackfirst[m][n].parentY);
 99         m = trackfirst[m][n].parentX;
100         n = trackfirst[m][n].parentY;
101         if(m == 0 && n == 0)
102             break;
103         if(m == -1 && n == -1)
104             break;
105         if(m == 1 && n == 0 || m == 4 && n == 3)
106             break;
107     }
108     printf("(0, 0)\n");
109 
110     这部分偏分,找到了父亲但是根本输不出来
111 
112     */
113     int t;
114 //    printf("(4, 4)\n");
115 //    printf("(4, 4)的父亲是:%d %d\n", trackfirst[4][4].parentX, trackfirst[4][4].parentY);
116 //    printf("(3, 4)的父亲是:%d %d\n", trackfirst[3][4].parentX, trackfirst[3][4].parentY);
117 //    printf("(2, 4)的父亲是:%d %d\n", trackfirst[2][4].parentX, trackfirst[2][4].parentY);
118 //    printf("(2, 3)的父亲是:%d %d\n", trackfirst[2][3].parentX, trackfirst[2][3].parentY);
119 //    printf("(2, 2)的父亲是:%d %d\n", trackfirst[2][2].parentX, trackfirst[2][2].parentY);
120 //    printf("(2, 1)的父亲是:%d %d\n", trackfirst[2][1].parentX, trackfirst[2][1].parentY);
121 //    printf("(2, 0)的父亲是:%d %d\n", trackfirst[2][0].parentX, trackfirst[2][0].parentY);
122 //    printf("(1, 0)的父亲是:%d %d\n", trackfirst[1][0].parentX, trackfirst[1][0].parentY);
123 //    printf("(0, 0)的父亲是:%d %d\n\n", trackfirst[0][0].parentX, trackfirst[0][0].parentY);
124 ////    while(trackfirst[m][n].parentX != -1 && trackfirst[m][n].parentY != -1){
125     int num = 0;
126     while(1){
127 //        printf("(%d, %d)\n", trackfirst[m][n].parentX, trackfirst[m][n].parentY);
128         mmaapp[num].x = trackfirst[m][n].parentX;
129         mmaapp[num++].y = trackfirst[m][n].parentY;
130         t = trackfirst[m][n].parentX;
131         n = trackfirst[m][n].parentY;
132         m = t;
133         if((m == 0) && (n == 0))
134             break;
135     }
136     for(int i = num - 1; i >= 0; i --){
137         printf("(%d, %d)\n", mmaapp[i].x, mmaapp[i].y);
138     }
139     printf("(4, 4)\n");
140 //    printf("(0, 0)\n");
141 
142 
143 //    printf("%d %d\n", trackfirst[3][0], trackfirst[4][0]);
144 //    printf("%d %d\n", trackfirst[3][0], trackfirst[3][0]);
145 //    int m = 4;
146 //    int n = 4;
147 //    int w = 0;
148 //    while(1){//想法一模一样就是实现太蠢了
149 ////int i = 3;
150 ////int j = 4;
151 //    w = 0;
152 //    for(int i = 0; i < 5; i ++ && !w)
153 //        for(int j = 0; j < 5; j ++ && !w)
154 //            for(int k = 0; k < 5; k ++ && !w){
155 //                if(trackfirst[i][k] == m && trackfirst[j][k] == n){
156 //                    printf("(%d, %d), %d\n", i, j, k);
157 //                    w = 1;
158 //                    m = i;
159 //                    n = j;
160 //                }
161 ////                if(m == 0 && n == 0){
162 ////                    i = 9;
163 ////                    j = 9;
164 ////                    break;
165 ////                }
166 //            }
167 //            if(m == 0 && n == 0)
168 //                    break;
169 //    }
170 }
171 
172 /*
173 01000
174 01010
175 00000
176 01110
177 00010
178 
179 
180 011
181 000
182 110
183 */

 

AC代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 struct trackfirst
  4 {
  5     int parentX;
  6     int parentY;
  7 }trackfirst[5][5];
  8 
  9 struct d
 10 {
 11     int x;
 12     int y;
 13 }mmaapp[1000000];
 14 int main()
 15 {
 16     freopen("C:\\Users\\GerJCS岛\\Desktop\\t.txt", "r", stdin);
 17     int minspace;
 18     for(int i = 0; i < 5; i ++)
 19         for(int j = 0; j < 5; j ++){
 20             trackfirst[i][j].parentX = -1;
 21             trackfirst[i][j].parentY = -1;
 22         }
 23     int pose[5][5];
 24     int save[500][500];
 25     int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
 26     int map[5][5];
 27     int queue[500][500];
 28     memset(save, 0, sizeof(save));
 29     memset(pose, 0, sizeof(pose));
 30     for(int i = 0; i < 5; i ++){
 31         for(int j = 0; j < 5; j ++)
 32             scanf("%d", &map[i][j]);
 33     }
 34     int x, y;
 35     int x1, y1;
 36     int q = 0;
 37     int pflag = 0;
 38     queue[q][0] = 0;
 39     queue[q ++][1] = 0;
 40     save[0][0] = 1;
 41     pose[0][0] = 1;
 42     while(pflag <= q)
 43     {
 44         x = queue[pflag][0];
 45         y = queue[pflag][1];
 46         int wp = 0;
 47         for(int i = 0; i < 4; i ++){
 48             x1 = x + dir[i][0];
 49             y1 = y + dir[i][1];
 50             if(x1 >= 0 && x1 < 5 && y1 >= 0 && y1 < 5 && map[x1][y1] == 0 && !save[x1][y1]){
 51                 queue[q][0] = x1;
 52                 queue[q++][1] = y1;
 53                 save[x1][y1] = 1;
 54                 pose[x1][y1] = pose[x][y] + 1;
 55 
 56                 if(i != 0){
 57                     trackfirst[x1][y1].parentX = x;
 58                     trackfirst[x1][y1].parentY = y;
 59                 }
 60 
 61                 if(x1 == 4 && y1 == 4){
 62                     minspace = pose[x1][y1];
 63                     break;
 64                 }
 65                 printf("##%d %d##\n", x1, y1);
 66             }
 67         }
 68         pflag ++;
 69     }
 70     int m = 4;
 71     int n = 4;
 72 
 73     int t;
 74     int num = 0;
 75     while(1){
 76         mmaapp[num].x = trackfirst[m][n].parentX;
 77         mmaapp[num++].y = trackfirst[m][n].parentY;
 78         t = trackfirst[m][n].parentX;
 79         n = trackfirst[m][n].parentY;
 80         m = t;
 81         if((m == 0) && (n == 0))
 82             break;
 83     }
 84     for(int i = num - 1; i >= 0; i --){
 85         printf("(%d, %d)\n", mmaapp[i].x, mmaapp[i].y);
 86     }
 87     printf("(4, 4)\n");
 88 }
 89 
 90 
 91 /*
 92 
 93 0 1 0 0 0
 94 0 1 0 1 0
 95 0 0 0 0 0
 96 0 1 1 1 0
 97 0 0 0 1 0
 98 
 99 0 1 1
100 0 0 0
101 1 1 0
102 
103 */

 

几次WA是因为Google浏览器自动翻译把英文的(4, 4)翻译成了(4,4)丢了空格QAQ~

 

 

****************************更新*******************************

 

参考博客:https://blog.csdn.net/u013480600/article/details/25486071

 结构体:https://baijiahao.baidu.com/s?id=1606137789197451791&wfr=spider&for=pc

 又学了一下队列和栈

IDE中的AC代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #include<stack>
 5 #include<algorithm>
 6 #define for(i ,a, b) for(int i = a; i < b; i ++)
 7 
 8 using namespace std;
 9 
10 struct Node{
11     int r, c;
12     Node(int r, int c):r(r), c(c){}
13     Node(){}//必须加
14 }parent[100][100];
15 
16 int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
17 int main()
18 {
19     freopen("C:\\Users\\GerJCS岛\\Desktop\\t.txt", "r", stdin);
20     int n = 5;
21     int maze[100][100];
22     int step[100][100];
23     int flag[100][100];
24     memset(maze, 0, sizeof(maze));
25     memset(flag, 0, sizeof(flag));
26     memset(step, 0, sizeof(step));
27     memset(parent, -1, sizeof(parent));
28 
29     for(i, 0, n)
30         for(j, 0, n)
31             scanf("%d", &maze[i][j]);
32 
33     queue<Node> Q;
34     while(!Q.empty()) Q.pop();
35     Q.push(Node(0, 0));
36     step[0][0] = 1;
37     flag[0][0] = 1;//一开始忘了
38     while(!Q.empty()){
39         Node node = Q.front(); Q.pop();
40         int r = node.r;
41         int c = node.c;
42         for(i, 0, 4){
43             int nowr = r + dir[i][0];
44             int nowc = c + dir[i][1];
45 //    printf("%d %d\n", parent[0][0].r, parent[0][0].c);
46             if(nowr >= 0 && nowr < 5 && nowc >= 0 && nowc < 5
47                && maze[nowr][nowc] == 0 && !flag[nowr][nowc]){
48                 flag[nowr][nowc] = 1;
49                 step[nowr][nowc] = step[r][c] + 1;
50 //                printf("%d %d %d\n", nowr, nowc, step[nowr][nowc]);
51                 Q.push(Node(nowr, nowc));//不可以写成node
52                 parent[nowr][nowc].r = r;
53                 parent[nowr][nowc].c = c;
54                 if(nowr == 4 && nowc == 4){//这句加不加效果一样???
55 //                    printf("$$%d %d %d$$\n", r, c, step[4][4]);
56                     break;
57                 }
58             }
59         }
60     }
61     stack<Node> S;
62     int r = 4;
63     int c = 4;
64     int t;
65     S.push(Node(4, 4));
66 //    printf("%d %d\n", parent[2][1].r, parent[2][1].c);
67 //    while(parent[r][c].r != -1 && parent[r][c].c != -1){/*之前这里出现了terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc的报错*/
68 //    while(parent[r][c].r != 0 || parent[r][c].c != 0){
69        while(1){
70         S.push(Node(parent[r][c].r, parent[r][c].c));
71 //        printf("%d %d\n", parent[r][c].r, parent[r][c].c);
72         t = parent[r][c].r;
73         c = parent[r][c].c;
74         r = t;
75         if(r == 0 && c == 0)
76             break;
77 //        printf("%d %d %d %d\n", parent[r][c].r, parent[r][c].c, r, c);
78     }
79 //    printf("#%d %d#\n", S.top().r, S.top().c);
80     while(!S.empty()){
81 //        Node node = S.front();
82         Node node = S.top();S.pop();
83         printf("(%d, %d)\n", node.r, node.c);
84     }
85 }

提交AC代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<queue>
 4 #include<stack>
 5 #include<algorithm>
 6 #define for(i ,a, b) for(int i = a; i < b; i ++)
 7 using namespace std;
 8 struct Node{
 9     int r, c;
10     Node(int r, int c):r(r), c(c){}
11     Node(){}//必须加
12 }parent[100][100];
13 int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
14 int main()
15 {
16     freopen("C:\\Users\\GerJCS岛\\Desktop\\t.txt", "r", stdin);
17     int n = 5;
18     int maze[100][100];
19     int step[100][100];
20     int flag[100][100];
21     memset(maze, 0, sizeof(maze));
22     memset(flag, 0, sizeof(flag));
23     memset(step, 0, sizeof(step));
24     memset(parent, -1, sizeof(parent));
25     for(i, 0, n)
26         for(j, 0, n)
27             scanf("%d", &maze[i][j]);
28     queue<Node> Q;
29     while(!Q.empty()) Q.pop();
30     Q.push(Node(0, 0));
31     step[0][0] = 1;
32     flag[0][0] = 1;//一开始忘了
33     while(!Q.empty()){
34         Node node = Q.front(); Q.pop();
35         int r = node.r;
36         int c = node.c;
37         for(i, 0, 4){
38             int nowr = r + dir[i][0];
39             int nowc = c + dir[i][1];
40             if(nowr >= 0 && nowr < 5 && nowc >= 0 && nowc < 5
41                && maze[nowr][nowc] == 0 && !flag[nowr][nowc]){
42                 flag[nowr][nowc] = 1;
43                 step[nowr][nowc] = step[r][c] + 1;
44                 Q.push(Node(nowr, nowc));//不可以写成node
45                 parent[nowr][nowc].r = r;
46                 parent[nowr][nowc].c = c;
47                 if(nowr == 4 && nowc == 4){//这句加不加效果一样???
48                     break;
49                 }
50             }
51         }
52     }
53     stack<Node> S;
54     int r = 4;
55     int c = 4;
56     int t;
57     S.push(Node(4, 4));
58        while(1){
59         S.push(Node(parent[r][c].r, parent[r][c].c));
60         t = parent[r][c].r;
61         c = parent[r][c].c;
62         r = t;
63         if(r == 0 && c == 0)
64             break;
65     }
66     while(!S.empty()){
67         Node node = S.top();S.pop();
68         printf("(%d, %d)\n", node.r, node.c);
69     }
70 }

 

 代码简洁清爽不少hhh~

posted @ 2019-03-26 21:22  GerJCS  阅读(587)  评论(0编辑  收藏  举报