Fork me on GitHub

POJ2251 Dungeon Master

目链(POJ)
题意翻译(洛谷)
 
AC代码:
 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 #include<queue>
 5 struct node
 6 {
 7     int x;
 8     int y;
 9     int z;
10     int step;
11 };
12 queue<node>q;
13 char map[30][30][30];
14 int vismap[30][30][30];
15 //int dir[6][3]={(0,-1,0),(0,1,0),(0,0,-1),(0,0,1),  (-1,0,0),(1,0,0)};//二维的上下左右和立体的上下(层)  先搁置,这个dir赋值有问题
16 int dir[6][3]={{0,-1,0},{0,1,0},{0,0,-1},{0,0,1},  {-1,0,0},{1,0,0}};//二维的上下左右和立体的上下(层)
17 int main()
18 {
19     int deep;
20 //    for(int i =0;i<6;i++)
21 //printf("%d %d %d\n", dir[i][0],dir[i][1],dir[i][2]);
22     int row, column;
23     while(cin>>deep>>row>>column && deep){
24         int canwalk=0;
25         getchar();
26         node Snode;
27         node Enode;
28         memset(map,0,sizeof map);
29         memset(vismap,0,sizeof vismap);
30         while(!q.empty()) //常规操作清空队列即初始化
31             q.pop();
32         for(int i=0;i<deep;i++)
33             for(int j=0;j<row;j++){
34                 for(int k=0;k<column;k++){
35                     cin>>map[i][j][k];
36                     if(map[i][j][k]=='S'){
37                         Snode.x=i;
38                         Snode.y=j;
39                         Snode.z=k;
40                         Snode.step=0;
41                         q.push(Snode);
42                         vismap[i][j][k]=1;
43                     }
44                     if(map[i][j][k]=='E'){
45                         Enode.x=i;
46                         Enode.y=j;
47                         Enode.z=k;
48                     }
49 
50                 }
51                 getchar();
52             }
53 
54             while(!q.empty())
55             {
56                 node thisnode;
57                 node nextnode;
58                 thisnode=q.front();
59                 q.pop();
60                 if(thisnode.x==Enode.x && thisnode.y==Enode.y && thisnode.z==Enode.z){
61                         canwalk=1;
62                     printf("Escaped in %d minute(s).\n", thisnode.step);
63                     break;
64                 }
65                 for(int i=0;i<6;i++)
66                 {
67                     nextnode.x=thisnode.x+dir[i][0];
68                     nextnode.y=thisnode.y+dir[i][1];
69                     nextnode.z=thisnode.z+dir[i][2];
70 //printf("^%d %d %d^\n", nextnode.x,nextnode.y,nextnode.z);
71                     if((0<=nextnode.x&& nextnode.x<deep) && (0<=nextnode.y&& nextnode.y<row) && (0<=nextnode.z&&nextnode.z<column))//边界值忘记加了一开始
72                     {
73 //                        printf("##%d %d %d step: %d\n", nextnode.x,nextnode.y,nextnode.z,nextnode.step);//发现根本没进入这个if判断
74 //                        printf("##%d\n", nextnode.x);//发现根本没进入这个if判断
75                         if(map[nextnode.x][nextnode.y][nextnode.z]=='.' || map[nextnode.x][nextnode.y][nextnode.z]=='E')
76                             if(vismap[nextnode.x][nextnode.y][nextnode.z]==0)
77                             {
78                                 nextnode.step=thisnode.step+1;
79                                 q.push(nextnode);
80                                 vismap[nextnode.x][nextnode.y][nextnode.z]=1;
81 
82                             }
83                     }
84 
85                 }
86             }
87             if(!canwalk)
88                 printf("Trapped!\n");
89     }
90 }

 

代码修改过程,思路详解:

---------------------------------------分割线---------------------------------------------------

我的代码现在回顾阶段暂时很严谨,就是说无论开数组还是剪枝与否,都可丁可卯,遇到超内存的去思考为什么不回溯就会超,而不是无脑剪枝无脑回溯,最后变个样子就不知道为啥不过了,比如数组,说最大50就开50,这样遇到没考虑的情况,比如可能会判断100这种,就知道哪里出了问题,不然直接开个150,AC了也稀里糊涂不透彻。头文件也是,用哪个写哪个,理解哪些需要对应哪个头文件而不是上来无脑写一堆,后期熟练了再这么写
 
之前理解的结构体实践发现有出入,参考博客参考博客
实际定义完结构体,可以直接用结构体名称即定义的类型去初始化定义新变量,根本不用在类型前加struct,下面代码可运行
 1 #include<stdio.h>
 2 struct stuff{
 3     char job[20];
 4     int age;
 5     float height;
 6 };
 7 stuff Huqinwei;
 8 int main()
 9 {
10 }
View Code

 

一开始运行啥也不输出

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 #include<queue>
 5 struct node
 6 {
 7     int x;
 8     int y;
 9     int z;
10     int step;
11 };
12 queue<node>q;
13 char map[30][30][30];
14 int vismap[30][30][30];
15 int dir[6][3]={(0,-1,0),(0,1,0),(0,0,-1),(0,0,1),  (-1,0,0),(1,0,0)};//二维的上下左右和立体的上下(层)
16 int main()
17 {
18     int deep;
19     int row, column;
20     while(cin>>deep>>row>>column && deep){
21         getchar();
22         node Snode;
23         node Enode;
24         memset(map,0,sizeof map);
25         memset(vismap,0,sizeof vismap);
26         while(!q.empty()) //常规操作清空队列即初始化
27             q.pop();
28         for(int i=0;i<deep;i++)
29             for(int j=0;j<row;j++){
30                 for(int k=0;k<column;k++){
31                     cin>>map[i][j][k];
32                     if(map[i][j][k]=='S'){
33                         Snode.x=i;
34                         Snode.y=j;
35                         Snode.z=k;
36                         Snode.step=0;
37                         q.push(Snode);
38                     }
39                     if(map[i][j][k]='E'){
40                         Enode.x=i;
41                         Enode.y=j;
42                         Enode.z=k;
43                     }
44                 }
45                 getchar();
46             }
47 //        for(int i=0;i<deep;i++)     //测验输入是否正确
48 //            for(int j=0;j<row;j++){
49 //                for(int k=0;k<column;k++)
50 //                    cout<<map[i][j][k];
51 //                cout << endl;
52 //            }
53             while(!q.empty())
54             {
55                 node thisnode;
56                 node nextnode;
57                 thisnode=q.front();
58                 q.pop();
59                 if(thisnode.x==Enode.x && thisnode.y==Enode.y && thisnode.z==Enode.z){
60                     printf("%d\n", thisnode.step);
61                     break;
62                 }
63                 for(int i=0;i<6;i++)
64                 {
65 printf("@@@\n");
66                     nextnode.x=thisnode.x+dir[i][0];
67                     nextnode.y=thisnode.y+dir[i][1];
68                     nextnode.z=thisnode.z+dir[i][2];
69                     if(map[nextnode.x][nextnode.y][nextnode.z]=='.'){
70                         nextnode.step=thisnode.step+1;
71                         q.push(nextnode);
72                     }
73 
74                 }
75             }
76     }
77 }
View Code

发现E根本没有进过队列

判断改成  if(map[nextnode.x][nextnode.y][nextnode.z]=='.' || map[nextnode.x][nextnode.y][nextnode.z]=='E' ,依旧不输出

 注:上面 if(map[i][j][k]=='E') 写错了,不过改了后还不对

然后把 printf("^%d %d %d^\n", nextnode.x,nextnode.y,nextnode.z); 这句来回加到某处,发现第一步走的不是定义的(0,-1,0),测试验证:

for(int i =0;i<6;i++)
    printf("%d %d %d\n", dir[i][0],dir[i][1],dir[i][2]);

先根据之前几年刷题经验大概改成这个中括号

int dir[6][3]={{0,-1,0},{0,1,0},{0,0,-1},{0,0,1},  {-1,0,0},{1,0,0}};//二维的上下左右和立体的上下()层)

原因后面找到了数组定义基本语法 ,后来测试发现括号的写法是乱输出的:

 1 #include<iostream>
 2 #include<string.h>
 3 using namespace std;
 4 #include<queue>
 5 
 6 int dir[2][2]={(7,8),(9,5)};//二维的上下左右和立体的上下(层)
 7 int main()
 8 {
 9     for(int i=0;i<2;i++)
10         printf("%d %d\n",dir[i][0],dir[i][1]);
11 }
View Code

改成后继续调试

加了个边界判断  if((0<=nextnode.x<deep) && (0<=nextnode.y<row) && (0<=nextnode.z<column)) ,发现下面nextnode.x是-1也可以输出,难道0<=-1?测试了下原来if里恒成立 if(0<-1<deep)//操,惊了,错误比较 printf("$"); ,参考博客

发现数据
1 3 3
S##
###
###
输出Escaped in 0 minute(s).而不是Trapped

加了个printf("$$%d%d%d\n", Enode.x,Enode.y,Enode.z);
输出$$000

发现因为E初始化就是0,但数据没有不输入E的情况,略过,如果有就初始化为-1

改了这些准备提交,洛谷的此题来源于UVA,懒得挂tizi(那俩字打出来发布不了)没加载出来,说是不稳定,印象里没注册过,就不去找回用了(10月份回来看此博客,洛谷绑定UVA提交洛谷也AC了),POJ今天9/3依旧挂了,找到可用的平台,POJ的图标,但数据拉过来了不错。

提交发现MLE,思考回溯意义,虽然不会导致WA但走过的再加进去就没必要,加了剪枝判断,AC了

 

 

提交记录:

 

草稿杂乱代码

  1 #include<iostream>
  2 #include<string.h>
  3 using namespace std;
  4 #include<queue>
  5 struct node
  6 {
  7     int x;
  8     int y;
  9     int z;
 10     int step;
 11 };
 12 queue<node>q;
 13 char map[30][30][30];
 14 int vismap[30][30][30];
 15 //int dir[6][3]={(0,-1,0),(0,1,0),(0,0,-1),(0,0,1),  (-1,0,0),(1,0,0)};//二维的上下左右和立体的上下(层)  先搁置,这个dir赋值有问题
 16 int dir[6][3]={{0,-1,0},{0,1,0},{0,0,-1},{0,0,1},  {-1,0,0},{1,0,0}};//二维的上下左右和立体的上下(层)
 17 int main()
 18 {
 19     int deep;
 20 //    for(int i =0;i<6;i++)
 21 //printf("%d %d %d\n", dir[i][0],dir[i][1],dir[i][2]);
 22     int row, column;
 23     while(cin>>deep>>row>>column && deep){
 24         int canwalk=0;
 25         getchar();
 26         node Snode;
 27         node Enode;
 28         memset(map,0,sizeof map);
 29         memset(vismap,0,sizeof vismap);
 30         while(!q.empty()) //常规操作清空队列即初始化
 31             q.pop();
 32         for(int i=0;i<deep;i++)
 33             for(int j=0;j<row;j++){
 34                 for(int k=0;k<column;k++){
 35                     cin>>map[i][j][k];
 36                     if(map[i][j][k]=='S'){
 37                         Snode.x=i;
 38                         Snode.y=j;
 39                         Snode.z=k;
 40                         Snode.step=0;
 41                         q.push(Snode);
 42                         vismap[i][j][k]=1;
 43                     }
 44                     if(map[i][j][k]=='E'){
 45                         Enode.x=i;
 46                         Enode.y=j;
 47                         Enode.z=k;
 48                     }
 49 
 50                 }
 51                 getchar();
 52             }
 53 
 54 //        for(int i=0;i<deep;i++)     //测验输入是否正确
 55 //            for(int j=0;j<row;j++){
 56 //                for(int k=0;k<column;k++)
 57 //                    cout<<map[i][j][k];
 58 //                cout << endl;
 59 //            }
 60 
 61 //1 3 3
 62 //S..
 63 //...
 64 //..E
 65 //            if(0<-1<deep)//操,惊了,错误比较:https://blog.csdn.net/HUAERBUSHI521/article/details/121704363
 66 //                printf("$");
 67 
 68 
 69 //printf("$$%d%d%d\n", Enode.x,Enode.y,Enode.z);
 70 ////发现1 3 3
 71 //S##
 72 //###
 73 //###
 74 //输出$$000
 75 //因为E初始化就是0,就是不一定输入E
 76 
 77             while(!q.empty())
 78             {
 79                 node thisnode;
 80                 node nextnode;
 81                 thisnode=q.front();
 82                 q.pop();
 83                 if(thisnode.x==Enode.x && thisnode.y==Enode.y && thisnode.z==Enode.z){
 84                         canwalk=1;
 85                     printf("Escaped in %d minute(s).\n", thisnode.step);
 86                     break;
 87                 }
 88                 for(int i=0;i<6;i++)
 89                 {
 90                     nextnode.x=thisnode.x+dir[i][0];
 91                     nextnode.y=thisnode.y+dir[i][1];
 92                     nextnode.z=thisnode.z+dir[i][2];
 93 ////printf("^%d %d %d^\n", nextnode.x,nextnode.y,nextnode.z);
 94                     if((0<=nextnode.x&& nextnode.x<deep) && (0<=nextnode.y&& nextnode.y<row) && (0<=nextnode.z&&nextnode.z<column))//边界值忘记加了一开始
 95                     {
 96 //                        printf("##%d %d %d step: %d\n", nextnode.x,nextnode.y,nextnode.z,nextnode.step);//发现根本没进入这个if判断
 97 //                        printf("##%d\n", nextnode.x);//发现根本没进入这个if判断
 98                         if(map[nextnode.x][nextnode.y][nextnode.z]=='.' || map[nextnode.x][nextnode.y][nextnode.z]=='E')
 99                             if(vismap[nextnode.x][nextnode.y][nextnode.z]==0)
100                             {
101                                 nextnode.step=thisnode.step+1;
102                                 q.push(nextnode);
103                                 vismap[nextnode.x][nextnode.y][nextnode.z]=1;
104 
105                             }
106                     }
107 
108                 }
109             }
110             if(!canwalk)
111                 printf("Trapped!\n");
112     }
113 }
114 
115 
116 
117 
118 //我垃圾,可以说想测试人低头,学,问
119 //
120 //但曾经的acm算法在我面前
121 //我想逃避,不想看,更不想入他这个圈
122 //
123 //眼不见心不烦
124 //
125 //亦或者说是逃避
126 //
127 //曾经linlinsong
128 //acm搞Java甚至工资没别人高
129 //
130 //全都是自己人说acm不值得的
131 //
132 //到头来那些人在哪里都隐退了,现在出来的leetcode呵呵,出来讲算法题的,什么公子龙什么哈工大吴师兄,我请教过问题。。陈越姥姥(垃圾谦虚吧)
133 
134 //我玩acm的时候,你们还没有出生。
135 //
136 //你们讲算法?西安培训的时候你们就是垃圾
137 //知错就改,这也用说?那些算竞圈的
View Code

 scanf有关的一切知识

posted @ 2024-09-01 21:04  GerJCS  阅读(5)  评论(0编辑  收藏  举报