POJ3984-迷宫问题
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 char path[26]={"A"}; 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 int main() 16 { 17 18 char answer[26]; 19 memset(map,0,sizeof map); 20 memset(vismap,0,sizeof vismap); 21 for(int i=0;i<5;i++) 22 for(int j=0;j<5;j++) 23 cin>>map[i][j]; 24 25 node Snode; 26 Snode.x=0; 27 Snode.y=0; 28 vismap[0][0]=1; 29 q.push(Snode); 30 node thisnode; 31 int len=sizeof(thisnode.path); 32 while(!q.empty()) 33 { 34 thisnode=q.front(); 35 q.pop(); 36 node nextnode; 37 if(thisnode.x==4&&thisnode.y==4) 38 { 39 memcpy(answer, thisnode.path, len); 40 vismap[nextnode.x][nextnode.y]=1; 41 break; 42 } 43 44 for(int i=0;i<4;i++){ 45 nextnode.x=thisnode.x+dir[i][0]; 46 nextnode.y=thisnode.y+dir[i][1]; 47 48 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5 49 &&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0 ){ 50 51 vismap[nextnode.x][nextnode.y]=1; 52 if(i==0) 53 { 54 memcpy(nextnode.path, thisnode.path, len); 55 strcat(nextnode.path,"0"); 56 } 57 if(i==1) 58 { 59 memcpy(nextnode.path, thisnode.path, len); 60 strcat(nextnode.path,"1"); 61 } 62 if(i==2) 63 { 64 memcpy(nextnode.path, thisnode.path, len); 65 strcat(nextnode.path,"2"); 66 } 67 if(i==3) 68 { 69 memcpy(nextnode.path, thisnode.path, len); 70 strcat(nextnode.path,"3"); 71 } 72 q.push(nextnode); 73 } 74 } 75 } 76 int reallen; 77 for(int i=0;i<len;i++){ 78 if(answer[i] == '\0'){ 79 reallen=i; 80 break; 81 } 82 } 83 printf("(0, 0)\n"); 84 for(int i=1;i<reallen;i++){ 85 Snode.x=Snode.x+dir[answer[i]-48][0];//这样加的是ASC,1的ASC是49,dir[49][0]不会报错但随机,所以要减去48 86 Snode.y=Snode.y+dir[answer[i]-48][1]; 87 printf("(%d, %d)\n", Snode.x,Snode.y); 88 89 } 90 }
------------------------------------------分割线-------------------------------------------------
以下修改过程以及思路:
初次草稿:
1 #include<iostream> 2 #include<string.h>//memset用的 3 using namespace std;//cout,cin,queue用的 4 #include<queue>//queue<node>q; 5 struct node 6 { 7 int x; 8 int y; 9 char path[26];//一开始定义的全局变量char path[5][5];感觉是5行5列的字符,而不是5行5列字符串 //https://qb.zuoyebang.com/xfe-question/question/234d44683fa655bd9af73f12e1f4e335.html 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 int main() 16 { 17 memset(map,0,sizeof map); 18 memset(vismap,0,sizeof vismap); 19 //强迫症总想看懂别人的代码,q神慰藉不看 20 // 输入多个数据不会了,只能想到第一个数字不是EOF,然后输入后面的,接下来循环输入4行 21 for(int i=0;i<5;i++) 22 for(int j=0;j<5;j++) 23 cin>>map[i][j];//思考scanf的话,map数组用不用加& 24 25 // for(int i=0;i<5;i++){//验证输入数据是否正确 26 // for(int j=0;j<5;j++) 27 // printf("%d ",map[i][j]); 28 // printf("\n"); 29 // } 30 // 方法一广搜得到最少步数,再深搜等于最少步数就return一步步输出,但有点der 31 // 方法二广搜记录每一步 32 33 34 // 字符拼接:https://blog.csdn.net/MrWangHao/article/details/130302421#:~:text=%E6%96%87%E7%AB%A0%E4%BB%8B%E7%BB%8D%E4%BA%86C%E8%AF%AD%E8%A8%80%E4%B8%AD%E7%94%A8 35 // char shr1[3]="32"; //shr1[2]="32"报错,理由长度定义少了:https://blog.csdn.net/weixin_45792414/article/details/125293580 36 // char str1[3]="32"; 37 // char str2[3]="01"; 38 // strcat(str1,str2); 39 // printf("%s\n",str1); 40 41 //#include<stdio.h> 42 //#include<string.h> 43 //int main() 44 //{ 45 // char str1[3]="32"; 46 // char str2[3]="01"; 47 // strcat(str1,"4"); 48 // printf("%s\n",str1); 49 //} 50 51 52 node Snode; 53 Snode.x=0; 54 Snode.y=0; 55 vismap[0][0]=1; 56 q.push(Snode); 57 while(!q.empty()) 58 { 59 node thisnode=q.front(); 60 node nextnode; 61 for(int i=0;i<4;i++){ 62 nextnode.x=thisnode.x+dir[i][0]; 63 nextnode.y=thisnode.y+dir[i][1]; 64 65 if(nextnode.x==4&&nextnode.y==4) 66 { 67 printf("!:%s\n",thisnode.path); 68 break; 69 } 70 71 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5&&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0){ 72 vismap[nextnode.x][nextnode.y]=1; 73 q.push(nextnode); 74 q.pop(); 75 if(i==0) 76 strcat(nextnode.path,"0");//艹字符串一堆东西要学,如果是字符的话这里是‘’ 还是“” 77 if(i==1) 78 strcat(nextnode.path,"1"); 79 if(i==2) 80 strcat(nextnode.path,"2"); 81 if(i==3) 82 strcat(nextnode.path,"3"); 83 } 84 } 85 } 86 87 88 } 89 90 91 92 93 94 95 96 //#include<iostream> 97 //#include<string.h>//memset用的 98 //using namespace std;//队列queue的pop push用的 99 //#include<queue>//这两个一起给queue队列操作提供头文件,先搁置 100 // 101 //int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 102 //int map[5][5]; 103 //int main() 104 //{ 105 //// for(int i=0;i<1;i++) 106 //// int a=1; 107 //// printf("%d\n",a); 108 // 109 //} 110 111 //#include <stdio.h> 112 // 113 //int main(void) 114 //{ 115 // int i=0; 116 // int sum=0; 117 // for(int sum=10,i=1;i<2;++i) 118 // sum+=i; 119 // printf("%d %d\n",i,sum); 120 //} 121 122 // 123 //#include <stdio.h> 124 //int main(void) 125 //{ 126 // for(int i=0;i<3;++i) 127 // int sum=3; 128 // printf("%d\n",sum); 129 //}https://bbs.csdn.net/topics/391956385#:~:text=%E5%A6%82%E6%9E%9C%E4%BD%A0%E6%98%AFC%E8%AF%AD%E8%A8%80%E7%BC%96%E8%AF%91, 130 //一群傻逼瞎说 131 132 //扯了这么多看似没啥意义但其实我也真不知道有啥用处的坑 133 //学strcat的时候发现定义了str老说我没定义,因为我是把这题代码写一半, 134 //用到拼接再测试写的,注释了一半最后发现for的问题, 135 //以为C语言用for定义2遍变量会报错没定义 136 //结果是for里的定义是无效定义 137 //所以注释一半写其他的还是可以学到一些东西的 138 139 140 141 //https://blog.csdn.net/weixin_43719752/article/details/120599794 142 // 虽然我啥也不会,但学了这么多年还是知道啥游泳啥咩有的,比如这个,就有预感,他没啥用 143 // 学性价比不搞 144 //搁置 145 // 146 //第一次觉得之前写的所有代码都有问题,是回顾了形参后 147 //第二次就是这次for里定义int,其实for里可以定义int,只是不能在for外面用 148 149 //C语言for里面不允许定义变量 150 151 //我念大学15年那时候编程也没这么多屁事啊 152 //https://www.cnblogs.com/xuyinghui/p/4937245.html#:~:text=%E4%B8%BA%E4%BB%80%E4%B9%88for%20(in 153 //一堆老头来闲的回改名字,跟USB一样,张宇讲过数学界的事 154 155 //第一次觉得后怕是知道阿辉讲的切弯技巧 156 157 //岛娘一样胡言乱语 158 159 //claires克拉丽丝 160 //现在还没毕业的岛娘谷歌 161 162 //W钰H说q神加一个数据wa一半人,又加一个wa一半人,租别墅一个与8k,克拉丽丝绩效最差 163 //如果超时,剩下的打表,骗取AC 164 //父亲血淋淋的脚换来的一筐核桃,导师嫌弃,送礼
简化版:
1 #include<iostream> 2 #include<string.h>//memset用的 3 using namespace std;//cout用的 4 #include<queue>//queue<node>q; 5 struct node 6 { 7 int x; 8 int y; 9 char path[26]; 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 int main() 16 { 17 memset(map,0,sizeof map); 18 memset(vismap,0,sizeof vismap); 19 for(int i=0;i<5;i++) 20 for(int j=0;j<5;j++) 21 cin>>map[i][j]; 22 23 24 25 node Snode; 26 Snode.x=0; 27 Snode.y=0; 28 vismap[0][0]=1; 29 q.push(Snode); 30 while(!q.empty()) 31 { 32 node thisnode=q.front(); 33 node nextnode; 34 for(int i=0;i<4;i++){ 35 nextnode.x=thisnode.x+dir[i][0]; 36 nextnode.y=thisnode.y+dir[i][1]; 37 38 if(nextnode.x==4&&nextnode.y==4) 39 { 40 printf("!:%s\n",thisnode.path); 41 break; 42 } 43 44 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5&&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0){ 45 vismap[nextnode.x][nextnode.y]=1; 46 q.push(nextnode); 47 q.pop(); 48 if(i==0) 49 strcat(nextnode.path,"0");//艹字符串一堆东西要学,如果是字符的话这里是‘’ 还是“” 50 if(i==1) 51 strcat(nextnode.path,"1"); 52 if(i==2) 53 strcat(nextnode.path,"2"); 54 if(i==3) 55 strcat(nextnode.path,"3"); 56 } 57 } 58 } 59 60 61 }
发现输出乱码,逐步检查发现第一个strcat赋值完就是乱码
好像是没初始化的事,单独拿出来测试,相当离谱诡异
#include<iostream> #include<string.h> using namespace std; #include<queue> struct node { int x; int y; char path[26]; }; int main() { node a; printf("%s\n",a.path); strcat(a.path,"13"); printf("%s\n",a.path); printf("-----------------\n"); node b; printf("%s\n",b.path); printf("-----------------\n"); node c; strcat(c.path,"13"); printf("%s\n",c.path); printf("-----------------\n"); } //这他么离奇,分别单独运行node a/b/c段代码结果居然不一样,整体运行结果又不一样,绝了!!!
记得之前有听说过局部要初始化,全局不用的事,但一直也没局部特意初始化过也没错过啊
继续测试惊呆了
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 char path[26]; 10 }; 11 int main() 12 { 13 int a; 14 printf("%d\n",a); 15 a++; 16 printf("%d\n-------\n",a); 17 18 int b; 19 printf("%d\n----\n",b); 20 21 int c; 22 c++; 23 printf("%s\n----\n",c); 24 } 25 //这他么还有点死循环的意思呢???
关于c语言main函数里定义变量必须初始化嘛: 解释相当透彻的参考博客
真给我写吐了,这根本不是搜索题,这他妈就是考验字符串的题目
nextnode 那个咋写都不对
草稿:
1 #include<iostream> 2 #include<string.h>//memset用的 3 using namespace std;//cout用的 4 #include<queue>//queue<node>q; 5 struct node 6 { 7 int x; 8 int y; 9 char path[26]; 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 int main() 16 { 17 memset(map,0,sizeof map); 18 memset(vismap,0,sizeof vismap); 19 for(int i=0;i<5;i++) 20 for(int j=0;j<5;j++) 21 cin>>map[i][j]; 22 23 node Snode; 24 Snode.x=0; 25 Snode.y=0; 26 vismap[0][0]=1; 27 q.push(Snode); 28 // printf("$$%s\n", Snode.path);//xy赋值完,path相应也初始化了 29 30 while(!q.empty()) 31 { 32 node thisnode=q.front(); 33 node nextnode; 34 // nextnode.x=0; 35 // nextnode.path="";//绝了报错,error: incompatible types in assignment of 'const char [1]' to 'char [26]' 卧槽无意间看到评论我博客的博主了:https://www.cnblogs.com/zhugesiying/p/dsy.html 36 // nextnode.path={' '};//见测试代码1 37 38 nextnode.x=Snode.x; 39 nextnode.y=Snode.y; 40 //nextnode.path=Snode.path;//草泥马写吐了干完活刷题 error: invalid array assignment 41 42 memcpy(nextnode.path, Snode.path, 26);//查了个招,这道题宁可叫做字符串题目 43 44 // printf("###%s\n", thisnode.path);/艹为啥上来就是“啰”啊 45 // printf("###%d\n", nextnode.x);//xy没赋值,x/y/path仨值都是随机的 46 47 // 怎么初始化没查到,根据文章“好像是没初始化的事,单独拿出来测试,相当离谱诡异”下的代码 和 48 // 上买面Snode输出正常,先把nextnode.x也设置成0,但没用,再试试把.path初始化了 49 50 for(int i=0;i<4;i++){ 51 nextnode.x=thisnode.x+dir[i][0]; 52 nextnode.y=thisnode.y+dir[i][1]; 53 54 if(nextnode.x==4&&nextnode.y==4) 55 { 56 printf("%s\n",thisnode.path); 57 break; 58 } 59 60 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5&&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0){ 61 vismap[nextnode.x][nextnode.y]=1; 62 q.push(nextnode); 63 q.pop(); 64 if(i==0) 65 strcat(nextnode.path,"0");//字符串一堆东西要学,如果是字符的话这里是‘’ 还是“” 66 if(i==1) 67 strcat(nextnode.path,"1"); 68 if(i==2) 69 strcat(nextnode.path,"2"); 70 if(i==3) 71 strcat(nextnode.path,"3"); 72 if(i==4) 73 strcat(nextnode.path,"4"); 74 } 75 } 76 } 77 } 78 79 80 //测试代码1: 81 //#include<stdio.h> 82 //int main() 83 //{ 84 // int arr[5]; // 声明一个固定大小的数组 85 //// arr = {1, 2, 3, 4, 5}; // 错误:不能直接将初始化列表赋值给数组 error: assigning to an array from an initializer list 86 // 87 // // 解决方法1:确保初始化列表元素数量与数组大小相同 88 // int data[] = {1, 2, 3, 4, 5,6}; 89 // for(int i = 0; i < 6; ++i) { 90 // arr[i] = data[i]; 91 // } 92 // for(int i=0;i<6;i++) 93 // printf("%d\n",arr[i]); 94 //} 95 // 96 // 97 ////这为啥可以输出6啊?但上面那行错误啊 98 ////定义的时候才能5行那样初始化:https://blog.csdn.net/weixin_41169280/article/details/109710098 99 ////那些考哈工程呢考非北邮的真是按部就班的垃圾,代码狗屎,呵呵,但学习能力 100 ////做核酸,三鹿奶粉,毒教材,医疗,农夫山泉非洲维族垃圾牲口竟帮扶国外傻逼捞好处,小机灵智能手表360,东方树叶,利民从来没有,外包畸形的傻逼,正义法律就是狗屁,新疆组织过的骑行团野炊烧烤呵呵 101 ////这是百度给的智能回答结果 102 103 104 105 106 107 //#include<stdio.h> 108 //struct node 109 //{ 110 // int x; 111 //}; 112 //int main() 113 //{ 114 // struct node a=30; 115 //} 116 117 118 //#include<stdio.h> 119 //struct example 120 //{ 121 // char str[20]; 122 //}; 123 // 124 //int main() { 125 // struct example ex = {"Hello, World!"}; 126 //} 127 //为啥百度智能回答的代码我变个样子写就错了啊
简洁版:
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 char path[26]; 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 int main() 16 { 17 memset(map,0,sizeof map); 18 memset(vismap,0,sizeof vismap); 19 for(int i=0;i<5;i++) 20 for(int j=0;j<5;j++) 21 cin>>map[i][j]; 22 23 node Snode; 24 Snode.x=0; 25 Snode.y=0; 26 vismap[0][0]=1; 27 q.push(Snode); 28 29 while(!q.empty()) 30 { 31 node thisnode=q.front(); 32 node nextnode; 33 34 nextnode.x=Snode.x; 35 nextnode.y=Snode.y; 36 memcpy(nextnode.path, Snode.path, 26); 37 38 for(int i=0;i<4;i++){ 39 nextnode.x=thisnode.x+dir[i][0]; 40 nextnode.y=thisnode.y+dir[i][1]; 41 42 if(nextnode.x==4&&nextnode.y==4) 43 { 44 printf("%s\n",thisnode.path); 45 break; 46 } 47 48 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5&&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0){ 49 vismap[nextnode.x][nextnode.y]=1; 50 q.push(nextnode); 51 q.pop(); 52 if(i==0) 53 strcat(nextnode.path,"0"); 54 if(i==1) 55 strcat(nextnode.path,"1"); 56 if(i==2) 57 strcat(nextnode.path,"2"); 58 if(i==3) 59 strcat(nextnode.path,"3"); 60 if(i==4) 61 strcat(nextnode.path,"4"); 62 } 63 } 64 } 65 }
输出全是0
小知识回顾:break只能跳出一层,之前写过的“Dungeon Master”break加载了外面一层,break刚好,如果加在for里面就会WA,除非在while队列非空判断那加一个如果canwalk==0或者把E的vismap记得赋值为1
1 #include<stdio.h> 2 int main() 3 { 4 for(int i=0;i<3;i++){ 5 for(int j=0;j<4;j++){ 6 if(j==2) 7 break; 8 printf("%d\n",j); 9 10 } 11 } 12 }
以后还是把break放在外面,即while队列空不空 和 for之间
检查发现strcat(nextnode.path,"1");有问题,应该是1拼接到上一个的path,这整体再赋给nextnode.path,但这样上一个path又改变了,把拼接改用赋值
琢磨好一阵子最后发现很贴近了
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 char path[26]={"A"}; 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 int main() 16 { 17 memset(map,0,sizeof map); 18 memset(vismap,0,sizeof vismap); 19 for(int i=0;i<5;i++) 20 for(int j=0;j<5;j++) 21 cin>>map[i][j]; 22 23 node Snode; 24 Snode.x=0; 25 Snode.y=0; 26 vismap[0][0]=1; 27 q.push(Snode); 28 while(!q.empty()) 29 { 30 node thisnode=q.front(); 31 node nextnode; 32 33 // nextnode.x=Snode.x; 34 // nextnode.y=Snode.y; 35 // memcpy(nextnode.path, Snode.path, 26); 36 37 for(int i=0;i<4;i++){ 38 nextnode.x=thisnode.x+dir[i][0]; 39 nextnode.y=thisnode.y+dir[i][1]; 40 //printf("*******%d %d\n",nextnode.x,nextnode.y); 41 if(nextnode.x==4&&nextnode.y==4&&vismap[nextnode.x][nextnode.y]==0) 42 { 43 printf("%s\n",thisnode.path); 44 vismap[nextnode.x][nextnode.y]=1; 45 break; 46 } 47 48 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5 49 &&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0){ 50 51 vismap[nextnode.x][nextnode.y]=1; 52 if(i==0) 53 { 54 int len=sizeof(thisnode.path); 55 memcpy(nextnode.path, thisnode.path, len); 56 strcat(nextnode.path,"0"); 57 // printf("#%s\n",nextnode.path); 58 } 59 if(i==1) 60 { 61 int len=sizeof(thisnode.path); 62 memcpy(nextnode.path, thisnode.path, len); 63 strcat(nextnode.path,"1"); 64 // printf("#%s\n",nextnode.path); 65 } 66 67 if(i==2) 68 { 69 int len=sizeof(thisnode.path); 70 memcpy(nextnode.path, thisnode.path, len); 71 strcat(nextnode.path,"2"); 72 // printf("#%s\n",nextnode.path); 73 } 74 if(i==3) 75 { 76 int len=sizeof(thisnode.path); 77 memcpy(nextnode.path, thisnode.path, len); 78 strcat(nextnode.path,"3"); 79 // printf("#%s\n",nextnode.path); 80 } 81 if(i==4) 82 { 83 int len=sizeof(thisnode.path); 84 memcpy(nextnode.path, thisnode.path, len); 85 strcat(nextnode.path,"4"); 86 // printf("#%s\n",nextnode.path); 87 } 88 if(i==5) 89 { 90 int len=sizeof(thisnode.path); 91 memcpy(nextnode.path, thisnode.path, len); 92 strcat(nextnode.path,"5"); 93 // printf("#%s\n",nextnode.path); 94 } 95 q.push(nextnode); 96 q.pop(); 97 98 99 } 100 } 101 } 102 } 103 104 105 106 107 108 //其他猫做不到,坏坏的微笑
搜索上没啥难度,主要在于很久不摸,不知道字符串咋用,这道题纯纯考察字符串的知识,踩了很多坑,都快赶上发明字符串了,有些甚至纯凭借多年前的字符串有那些用法的记忆来写,现查,其实挺基础的模板题感觉是,上面代码路线对了,维度输出后正确路线后好像又在哪里死循环了,备注:我的0123代表上下左右
这道题一开始想了很多思路,比如5*5的队列但要在结构体里定义队列有点复杂,又想定义个5*5的字符串数组,每个位置存一串路径比如012233就是上下左左右右,但不行啊,查了下二维字符串数组没有,只有二维字符数组,以为是5行5列的字符串,结果是5行5列的字符。不去看题解是不想思维定势,那样边看题解边写题一点意义没有,这么多年acm狗屁不是但耳濡目染理论还是相当有的,最后想到结构体里定义个字符串
言归正传,这个后面死循环了是因为,q.pop();这句话应该紧跟q.front后面,搞出来一个,就得pop,而不是放在if里判断完再决定弹不弹出。还有个地方,由于这个题特殊,所以q.push(nextnode);要在nextnode赋好值,即把0123哪个方向加进去的后面再写,感觉这样更加清晰了,而不是拿到BFS无脑poppush的
重新理解for里面定义的问题
1 #include<stdio.h> 2 int main() 3 { 4 for(int i=0;i<10;i++){ 5 int len=3; 6 printf("%d\n",i+len); 7 8 } 9 } 10 11 12 #include <stdio.h> 13 int main() 14 { 15 for(int i=0;i<3;++i) 16 int sum=3; 17 printf("%d\n",i+sum); 18 } 19 //懂了,for里面定义的只能自己用
写的过程遇到的坑,局部变量,代码块的作用域
1 #include<stdio.h> 2 int main() 3 { 4 int n=5; 5 while(n--) 6 { 7 if(1<2) 8 int m=3; 9 for(int i=0;i<10;i++) 10 { 11 printf("%d\n",m); 12 } 13 } 14 } 15 //每一个代码块都只能用自己定义的,这里printf里的m未定义,去掉if就好了
补基础,if语句分号的作用相当于空语句
1 #include<stdio.h> 2 int main() 3 { 4 if(1>2); 5 printf("#"); 6 }
第一次提交
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 char path[26]={"A"}; 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 int main() 16 { 17 18 char answer[26]; 19 memset(map,0,sizeof map); 20 memset(vismap,0,sizeof vismap); 21 for(int i=0;i<5;i++) 22 for(int j=0;j<5;j++) 23 cin>>map[i][j]; 24 25 node Snode; 26 Snode.x=0; 27 Snode.y=0; 28 vismap[0][0]=1; 29 q.push(Snode); 30 node thisnode; 31 int len=sizeof(thisnode.path); 32 while(!q.empty()) 33 { 34 thisnode=q.front(); 35 q.pop(); 36 node nextnode; 37 if(thisnode.x==4&&thisnode.y==4) 38 { 39 // printf("%s\n",thisnode.path); 40 memcpy(answer, thisnode.path, len); 41 vismap[nextnode.x][nextnode.y]=1; 42 break; 43 } 44 45 for(int i=0;i<4;i++){ 46 nextnode.x=thisnode.x+dir[i][0]; 47 nextnode.y=thisnode.y+dir[i][1]; 48 49 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5 50 &&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0 ){ 51 52 vismap[nextnode.x][nextnode.y]=1; 53 if(i==0) 54 { 55 memcpy(nextnode.path, thisnode.path, len); 56 strcat(nextnode.path,"0"); 57 } 58 if(i==1) 59 { 60 memcpy(nextnode.path, thisnode.path, len); 61 strcat(nextnode.path,"1"); 62 } 63 if(i==2) 64 { 65 memcpy(nextnode.path, thisnode.path, len); 66 strcat(nextnode.path,"2"); 67 } 68 if(i==3) 69 { 70 memcpy(nextnode.path, thisnode.path, len); 71 strcat(nextnode.path,"3"); 72 } 73 q.push(nextnode); 74 } 75 } 76 } 77 // printf("%s\n",answer); 78 // printf("%d\n",sizeof(answer));//艹,给我整不会了,本来想获取下answer长度的,然后遍历,0123对应具体走法 79 int reallen; 80 for(int i=0;i<len;i++){ 81 if(answer[i] == '\0'){ 82 // reallen=i; 83 // printf("%d\n", i);//相当愚蠢的获取真实长度的方法 84 reallen=i; 85 break; 86 } 87 } 88 printf("(0, 0)\n"); 89 // printf("#%d\n",reallen); 90 for(int i=1;i<reallen;i++){ 91 Snode.x=Snode.x+dir[answer[i]-48][0];//这样加的是ASC,1的ASC是49,dir[49][0]不会报错但随机,所以要减去48 92 Snode.y=Snode.y+dir[answer[i]-48][1]; 93 printf("(%d, %d)\n", Snode.x,Snode.y); 94 95 // printf("%d\n",answer[i]);//艹忘记了ASC码,1字符是49 96 } 97 // printf("^^^%d\n", dir[49][0]); 98 } 99 100 101 102 103 //这代码写的估计过阵子我自己都看不懂,强迫症想看懂别人代码 104 105 106 107 //#include<stdio.h>//输出超过定义数组的情况:https://ask.csdn.net/questions/7606652 108 //int main() 109 //{ 110 // int a[3]; 111 // printf("%d",a[5]); 112 //} 113 //ACM数组越界WA,RE都有可能:https://blog.csdn.net/JungleZRD/article/details/130452102 114 115 116 //#include<stdio.h> 117 //int main() 118 //{ 119 // char a='1'; 120 // int b=a-48; 121 // printf("%d",b); 122 //} 123 //好像可以这么搞,字符-整型
第一次提交居然AC了,这道题不用多组输入吗
回头解决所有遇到字符串以及其他问题
人们擅长把自己无法理解的东西强行加些解释,使得自圆其说,接下来尽量按照自己理解尽可能解决这道题遇到的诸多疑惑
###:char path[26]={"A"};这句如果没有A是个乱字符,但WA了??改了好几遍发现只有我这种写法能AC,下面找到了问题所在
测试代码:
1 #include<stdio.h> 2 #include<string.h> 3 struct node 4 { 5 int x; 6 int y; 7 char path[26]; 8 }; 9 int main() 10 { 11 node a; 12 printf("#%s#\n",a.path); 13 strcat(a.path,"13"); 14 printf("#%s#\n",a.path); 15 printf("-----------------\n"); 16 17 node b; 18 printf("#%s#\n",b.path); 19 printf("-----------------\n"); 20 21 node c; 22 strcat(c.path,"13"); 23 printf("#%s#\n",c.path); 24 printf("-----------------\n"); 25 }
输出结果是
整体运行结果 ## #13# ----------------- #啰?# ----------------- #13# -----------------
单独运行a/c段与整体运行相符
单独运行b段就不同了,
#@#
正如上面“解释相当透彻的参考博客”超链接里说的,微软会设置个不常用的数字给未定义的,使得人们不会使用出错,这样看到如此异常的数字就知道是未定义了,比如我输出b.path的ASC发现是个还几位的数字。随机分配可能看电影看视频或者其他行为导致哪块空闲分配哪块的空间
而这段代码:
1 #include<stdio.h> 2 #include<string.h> 3 struct node 4 { 5 int x; 6 int y; 7 char path[26]; 8 }; 9 int main() 10 { 11 node b; 12 printf("#%s#\n",b.path); 13 printf("-----------------\n"); 14 15 node c; 16 printf("#%s#\n",c.path); 17 printf("-----------------\n"); 18 19 node d; 20 printf("#%s#\n",d.path); 21 printf("-----------------\n"); 22 23 node e; 24 printf("#%s#\n",e.path); 25 printf("-----------------\n"); 26 27 node f; 28 printf("#%s#\n",f.path); 29 printf("-----------------\n"); 30 31 }
执行了多次b,输出居然是
#@# ----------------- ## ----------------- # ----------------- ## ----------------- #P? -----------------
看到上面赋值的,也就是a/c两段strcat代码会讲随机乱字符覆盖掉,再进一步测试是否真如此
由此可见哪怕拼接了,是否把随机值抹掉也是随机的,至此未定义的问题得到解决,这也是为什么一开始必须初始化个A,不然随机分配个乱字符,可能占多个位置,导致最后输出的结果字符串并不是从第二位起就是正确的
多举几个例子,印象深刻
可见bcd一开始是对的也是巧合,另外path、path1、path2这仨里的path,ASC是6422000,好像还有向前吃一位的功能,综上字符串没有赋值,只有拼接,真坑人,只能初始化个A,想设置为空都不行
###:遗留个问题等刷字符串时候再搞
就是定义字符串,输出如果不是“%s”,而是“%c”会怎样?
反正这里是把#都给吃掉了
###:单引号双引号问题
###:字符串数组和字符串指针赋值问题
1 #include<stdio.h> 2 #include<string.h> 3 char path[4]; 4 int main() 5 { 6 path[4] = "sds";//error: invalid conversion from 'const char*' to 'char' [-fpermissive] 7 path = "sds";//error: invalid array assignment 8 path = "ds";//error: incompatible types in assignment of 'const char [3]' to 'char [4]'| 9 }
只能定义的时候赋值,那字符串初始化用啥啊?先赋值个A,然后最后答案从A后开始算,这么智障吗?搁置
###:scanf输入char字符必须加&,字符串的时候不用加&,加了会怎样?搁置
###:字符串好头疼啊,找到个初始化的招,str[0]='\0';
AC代码基础上加了个str[0]='\0'和输出answer,其实终点的时候,thisnode.path就是这个乱码
经过在各种位置printf发现了,代码:
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 char path[26]; 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 int main() 16 { 17 18 char answer[26]; 19 memset(map,0,sizeof map); 20 memset(vismap,0,sizeof vismap); 21 for(int i=0;i<5;i++) 22 for(int j=0;j<5;j++) 23 cin>>map[i][j]; 24 25 node Snode; 26 Snode.x=0; 27 Snode.y=0; 28 vismap[0][0]=1; 29 q.push(Snode); 30 node thisnode; 31 thisnode.path[0]='\0'; 32 int len=sizeof(thisnode.path); 33 printf("%d\n",len); 34 printf("#%s#\n",thisnode.path); 35 printf("******%s*******\n",Snode.path); 36 while(!q.empty()) 37 { 38 thisnode=q.front(); 39 printf("^^^^^^%s^^^^^^\n",thisnode.path); 40 q.pop(); 41 node nextnode; 42 if(thisnode.x==4&&thisnode.y==4) 43 { 44 printf("%s\n",thisnode.path); 45 break; 46 } 47 48 for(int i=0;i<4;i++){ 49 nextnode.x=thisnode.x+dir[i][0]; 50 nextnode.y=thisnode.y+dir[i][1]; 51 52 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5 53 &&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0 ){ 54 55 vismap[nextnode.x][nextnode.y]=1; 56 if(i==0) 57 { 58 memcpy(nextnode.path, thisnode.path, len); 59 strcat(nextnode.path,"0"); 60 } 61 if(i==1) 62 { 63 memcpy(nextnode.path, thisnode.path, len); 64 strcat(nextnode.path,"1"); 65 } 66 if(i==2) 67 { 68 memcpy(nextnode.path, thisnode.path, len); 69 strcat(nextnode.path,"2"); 70 } 71 if(i==3) 72 { 73 memcpy(nextnode.path, thisnode.path, len); 74 strcat(nextnode.path,"3"); 75 } 76 q.push(nextnode); 77 } 78 } 79 } 80 // printf("__%s\n",answer); 81 // int reallen; 82 // for(int i=0;i<len;i++){ 83 // if(answer[i] == '\0'){ 84 // reallen=i; 85 // break; 86 // } 87 // } 88 // printf("(0, 0)\n"); 89 // for(int i=1;i<reallen;i++){ 90 // Snode.x=Snode.x+dir[answer[i]-48][0];//这样加的是ASC,1的ASC是49,dir[49][0]不会报错但随机,所以要减去48 91 // Snode.y=Snode.y+dir[answer[i]-48][1]; 92 // printf("(%d, %d)\n", Snode.x,Snode.y); 93 // } 94 }
实际执行发现
图一:
图二:
差别是我仅仅注释掉了20/21行的char
没初始化的变量都有问题,对了就是巧合,这里定义的answer和Snode.path,都没初始化,把answer和Snode.path输出整型,也就是地址,一个是地址984什么都没有,一个是地址944啰乱码且占了不止一个字符,都只是随机分到了这个,下一次开机或者看个视频,其他内存块有位置,就又会放到其他内存块,值又不一定是什么了。
只有Snode.path的时候,地址976是个空格。
上面测试过,没初始化的字符串,可能是空,可能真啥也没有,都是随机的
甚至在while(!q.empty())前加一个return 0;Snode.path有不一样了,估计根据代码长度分配哪个内存,可以理解。
然后我输出啰那个乱码,发现是6
也就理解了为啥AC代码不写初始化A会WA了,不止在前面补了一个字符啊这是
实验几个输出:
1 char r='1'; 2 printf("$$%c$$\n",r);//输出1 3 printf("$$%d$$\n",r);//输出49 4 // printf("$$%s$$\n",r);//运行错误 5 6 char w[3]="1"; 7 printf("$$%s$$\n",w);//输出1 8 printf("$$%d$$\n",w);//输出6422044
字符用%s会错误
字符串用%c乱码
综上,this.path有问题是Snode.path没'\0',因为是Snode最先压入队列的,改下就好了,多么简单的字符串初始化,查一堆文章狗放屁说什么乱七八糟的,那是赋值!!不是初始化,垃圾玩意耽误我这么久
###:我写main不写return,但好像return 0和return 1都没啥问题呢?可是把AC代码加个return 0;没问题,加个return 1;就RE。
###:看字符长度没法用sizeof,定义好了26个字符长度的字符串len就是26,除非用‘\0’来找真实长度
###:综上,修改后出现更简洁干净标准的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 char path[26]; 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 int main() 16 { 17 memset(map,0,sizeof map); 18 memset(vismap,0,sizeof vismap); 19 for(int i=0;i<5;i++) 20 for(int j=0;j<5;j++) 21 cin>>map[i][j]; 22 23 node Snode; 24 Snode.x=0; 25 Snode.y=0; 26 Snode.path[0]='\0'; 27 vismap[0][0]=1; 28 q.push(Snode); 29 node thisnode; 30 while(!q.empty()) 31 { 32 thisnode=q.front(); 33 // printf("^^^^^^%s^^^^^^\n",thisnode.path); 34 q.pop(); 35 node nextnode; 36 if(thisnode.x==4&&thisnode.y==4) 37 { 38 // printf("%s\n",thisnode.path); 39 break; 40 } 41 42 for(int i=0;i<4;i++){ 43 nextnode.x=thisnode.x+dir[i][0]; 44 nextnode.y=thisnode.y+dir[i][1]; 45 46 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5 47 &&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0 ){ 48 49 vismap[nextnode.x][nextnode.y]=1; 50 if(i==0) 51 { 52 memcpy(nextnode.path, thisnode.path, 26); 53 strcat(nextnode.path,"0"); 54 } 55 if(i==1) 56 { 57 memcpy(nextnode.path, thisnode.path, 26); 58 strcat(nextnode.path,"1"); 59 } 60 if(i==2) 61 { 62 memcpy(nextnode.path, thisnode.path, 26); 63 strcat(nextnode.path,"2"); 64 } 65 if(i==3) 66 { 67 memcpy(nextnode.path, thisnode.path, 26); 68 strcat(nextnode.path,"3"); 69 } 70 q.push(nextnode); 71 } 72 } 73 } 74 int reallen; 75 for(int i=0;i<26;i++){ 76 if(thisnode.path[i] == '\0'){ 77 reallen=i; 78 break; 79 } 80 } 81 printf("(0, 0)\n"); 82 for(int i=0;i<reallen;i++){ 83 Snode.x=Snode.x+dir[thisnode.path[i]-48][0]; 84 Snode.y=Snode.y+dir[thisnode.path[i]-48][1]; 85 printf("(%d, %d)\n", Snode.x,Snode.y); 86 } 87 }
###:AC有太多巧合了,写法随便选一种就可能对了,但不知道其他写法为啥错,现在AC过去这么久才彻底搞懂能想到的所有写法,和踩的坑,不至于下次用其他写法发现WA了又不知道为啥
全局定义结构体,是其一,其二如果
1 node thisnode; 2 node Snode;
这两句话放在全局main之前去定义也是最干净的,不需要'\0'
###:AC代码Ctrl+Z是将程序暂停,所以默认map全都初始化(0,0)了
###:至此全部疑问解决,但有一个
字符串数组越界问题
对于上面代码有句 Snode.x=Snode.x+dir[answer[i]][0];//这样加的是ASC,1的ASC是49,dir[49][0]不会报错但随机?,无意间写了个这个,dir[49][0]越界了啊,而且上面越界那个博客也是,只能先这样按照博客博主那样理解了,acm中越界可能会WA可能RE还是别越界
1 #include<stdio.h> 2 #include<iostream> 3 using namespace std; 4 #include<math.h> 5 void dfs(unsigned long long int nok, int post); 6 int n, pp; 7 int map[3]; 8 9 int j; 10 int queue = 12; 11 int main() 12 { 13 int max = 0; 14 for(int i = 0; i < 17; i++) 15 // { 16 printf("%d",map[i]); 17 // printf("%d\n",map[i]); 18 // if(max < map[i]) 19 // { 20 // max = map[i]; 21 // printf("###%d\n",max); 22 // j = i; 23 // } 24 // } 25 // cout << max << " " << j; 26 }
越界的数是随机输出的
###:博客园的BUG:选中超链接的文字,点下面“更多”“保存修改并编辑”,会把超链接删掉
========================================================================
至此这道题结束,这道题其实主要是字符串的问题,之前都是整型,哪怕不初始化后面也会赋值,而字符串一开始想初始化的时候还看了一堆无用狗屁文章,不知道怎么初始化无奈先搞成A,字符串赋值还很另类,特有的拼接如果上一个没初始化又会拼接上乱码,所以还是得回到初始化上,咋找找不到初始化方法,多亏了“初始化的招”文章
每天作息间最近图库 14点起,玩手机,16点吃第一顿饭去图书馆,学会玩会,22:30出来。还盒子柜子,23:15吃晚饭,通宵手机游戏各种sy到6点7点睡觉。反复 hahacode日常浏览pron p站 pornhub hihicode 总是改不掉回忆过去,去找去确认过去记录的痕迹是否真的有记录 沉默王二文章:秋招七宗罪“色欲 一直有” “之前一天5/6管子,这两天骑车没空导了,再tm骑几天都不会导了” 跟超哥吃饭,跟黑哥酒店 像个男受
思考方法二,发现不管是不是最优解,多种思路勤写一写有好处的,写完发现真有必要,反复回忆去修改之前的搜索博客,和巩固加深搜索思想和各种细节。
DFS不可以break,因为找到的不一定是最优解,要全搜出来,用return,这里特殊是因为知道minstep必定是结果,不用再往下深搜了,不要被误导
AC代码:广搜+深搜+数组模拟栈
广搜确定最少步数minstep,再深搜当step和minstep相等做个isfind标记,之后返回isfind是1就不再搜索,一直存入栈并return,最后输出这个数组模拟的栈,很简单注意样例输出9行实际是8走步就好,输出那里是 i<=minstep 而非单小于是因为memset过,没在栈里的就是初始值(0,0),正好输出(0,0)
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 step; 10 }; 11 queue<node>q; 12 int vismap[5][5]; 13 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 14 int map[5][5]; 15 node Snode; 16 node thisnode; 17 int minstep; 18 int answer[25][2]; 19 //int find;//error: reference to 'find' is ambiguous 引用非法 map同样是绿色为啥没事 20 int isfind; 21 void dfs(int x,int y,int step) 22 { 23 int thisx; 24 int thisy; 25 if(step==minstep) 26 return; 27 for(int i=0;i<4;i++) 28 { 29 thisx=x+dir[i][0]; 30 thisy=y+dir[i][1];//上下左右走的时候(0,0)也会进来,所以要vismap[0][0]=1; 31 if(0<=thisx&&thisx<5&&0<=thisy&&thisy<5 32 &&!vismap[thisx][thisy]&&map[thisx][thisy]==0){ 33 if(thisx==4&&thisy==4&&step==(minstep-1)){ 34 answer[step+1][0]=4; 35 answer[step+1][1]=4; 36 isfind=1; 37 return; 38 } 39 vismap[thisx][thisy]=1; 40 step++; 41 dfs(thisx,thisy,step); 42 if(isfind==1) 43 { 44 answer[step][0]=thisx; 45 answer[step][1]=thisy; 46 return; 47 } 48 step--; 49 vismap[thisx][thisy]=0; 50 } 51 52 } 53 } 54 int main() 55 { 56 isfind=0; 57 memset(answer,0,sizeof answer); 58 memset(map,0,sizeof map); 59 memset(vismap,0,sizeof vismap); 60 for(int i=0;i<5;i++) 61 for(int j=0;j<5;j++) 62 cin>>map[i][j]; 63 q.push(Snode); 64 vismap[0][0]=1; 65 while(!q.empty()) 66 { 67 thisnode=q.front(); 68 q.pop(); 69 node nextnode; 70 if(thisnode.x==4&&thisnode.y==4) 71 { 72 minstep=thisnode.step; 73 break; 74 } 75 76 for(int i=0;i<4;i++){ 77 nextnode.x=thisnode.x+dir[i][0]; 78 nextnode.y=thisnode.y+dir[i][1]; 79 80 if(0<=nextnode.x&&nextnode.x<5&&0<=nextnode.y&&nextnode.y<5 81 &&!vismap[nextnode.x][nextnode.y]&&map[nextnode.x][nextnode.y]==0 ){ 82 83 vismap[nextnode.x][nextnode.y]=1; 84 nextnode.step=thisnode.step+1; 85 q.push(nextnode); 86 } 87 } 88 } 89 //至此找到最短步骤minstep步 90 memset(vismap,0,sizeof vismap); 91 vismap[0][0]=1; 92 dfs(0,0,0); 93 for(int i=0;i<=minstep;i++) 94 printf("(%d, %d)\n",answer[i][0],answer[i][1]); 95 }
###:期间遇到了19报错 int find;//error: reference to 'find' is ambiguous 引用的find模棱两可非法,同样是绿色关键字,map为啥就没事??搁置,没用过map和find
###:新学的栈
AC代码:广搜+深搜+STL栈
1 #include<iostream> 2 #include<string.h> 3 using namespace std; 4 #include<queue> 5 #include<stack> 6 struct node 7 { 8 int x; 9 int y; 10 int step; 11 }; 12 struct Stacknode 13 { 14 int x; 15 int y; 16 }; 17 Stacknode stacknode; 18 queue<node>q; 19 stack<Stacknode>stackq; 20 int vismap[5][5]; 21 int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};//上下左右 22 int map[5][5]; 23 node Snode; 24 node thisnode; 25 26 int minstep; 27 int isfind; 28 int legal(int x,int y) 29 { 30 if(0<=x&&x<5&&0<=y&&y<5&&!vismap[x][y]&&map[x][y]==0) 31 return 1; 32 else 33 return 0; 34 } 35 void dfs(int x,int y,int step) 36 { 37 int thisx; 38 int thisy; 39 if(step==minstep) 40 return; 41 for(int i=0;i<4;i++) 42 { 43 thisx=x+dir[i][0]; 44 thisy=y+dir[i][1]; 45 if(legal(thisx,thisy)){ 46 if(thisx==4&&thisy==4&&step==(minstep-1)){ 47 48 stacknode.x=4; 49 stacknode.y=4; 50 stackq.push(stacknode); 51 isfind=1; 52 return; 53 } 54 vismap[thisx][thisy]=1; 55 step++; 56 dfs(thisx,thisy,step); 57 if(isfind==1) 58 { 59 stacknode.x=thisx; 60 stacknode.y=thisy; 61 stackq.push(stacknode); 62 return; 63 } 64 step--; 65 vismap[thisx][thisy]=0; 66 } 67 68 } 69 } 70 int main() 71 { 72 isfind=0; 73 memset(map,0,sizeof map); 74 memset(vismap,0,sizeof vismap); 75 76 for(int i=0;i<5;i++) 77 for(int j=0;j<5;j++) 78 cin>>map[i][j]; 79 q.push(Snode); 80 vismap[0][0]=1; 81 while(!q.empty()) 82 { 83 thisnode=q.front(); 84 q.pop(); 85 node nextnode; 86 if(thisnode.x==4&&thisnode.y==4) 87 { 88 minstep=thisnode.step; 89 break; 90 } 91 92 for(int i=0;i<4;i++){ 93 nextnode.x=thisnode.x+dir[i][0]; 94 nextnode.y=thisnode.y+dir[i][1]; 95 96 if(legal(nextnode.x,nextnode.y)){ 97 98 vismap[nextnode.x][nextnode.y]=1; 99 nextnode.step=thisnode.step+1; 100 q.push(nextnode); 101 } 102 } 103 } 104 //至此找到最短步骤minstep步 105 memset(vismap,0,sizeof vismap); 106 vismap[0][0]=1; 107 dfs(0,0,0); 108 stacknode.x=0; 109 stacknode.y=0; 110 stackq.push(stacknode); 111 while(!stackq.empty()) 112 { 113 stacknode=stackq.top(); 114 printf("(%d, %d)\n",stacknode.x,stacknode.y); 115 stackq.pop(); 116 } 117 118 119 }
###:一直不想学新东西,开始面对挑战
接下来开始看题解,看看大家都用什么方法做的
发现可以在结构体里用两个int存步骤,不用字符串,参考博客,思路好像比我的还清晰好理解
今天无意间发现POJ终于好了,从8/23炸到9/10
HDOJ和洛谷才有可能自己造数据,这题只有poj有,但数据太弱太弱了,这平台数据也是拉POJ的,
另一个人的题解博客,但问题好大啊,POJ居然能AC,数据弱的离谱,因为我发现他vis是按照右下上左顺序来的,第一次搜到啥是啥,根本没回溯,我把向上的if调到最上面,直接WA。
这傻逼把5搞成n是嫌代码不够麻烦吗,放一堆没用头文件,他估计都不知道哪个头文件是干嘛的,这就是我前面说的无脑堆,智障一个,而且好像连数组从0开始都不知道,POJ就把这代码AC了??
期间遇到memset的问题,memset只能初始化为0。数组初始化、二维数组初始化
傻逼百度误人子弟,最后一种根本不行
CNM!!这必应搜的是百度的结果,之前不是这样的啊!!把chrome改成默认必应也tm一样是百度,firefox火狐的developer开发版没事
火狐必应的搜索结果链接复制出来妈的也是百度,B站解决办法ww2/ww4也不行了,最后这里解决了,快捷方式属性里的目标有个多余的链接删掉再重启下,不然不生效,我都快一个月没关机了,之前电脑找不到3F0硬盘放电才好
CNM心累,过一会又被劫持了,快捷方式属性里的也是对的,直接重启又好了
为了装个长截图插件开tizi下,死慢,然后到家开机写代码又提示找不到设设备3F0,30s放电后开机了但网又上不去了妈的,记得之前开tizi后就这样,IE设置里重置网络就行,但win10IE设置没重置网络,各种查,都不行,网络提示说无法自动检测此网络代理设置,又开了下tizi,就好了,关掉也可以了。
言归正传,这小子不走寻常路有点自创算法的意思,给了我很大启发,突然有一丝丝觉得这人代码思维好像是降维打击,就是说针对终点在其他位置不对,但在右下角是对的,但我找出了反例,这人的代码右下上左还不回溯,那我直接
0 0 1 1 1 0 0 1 1 1 0 1 1 1 1 0 1 1 1 1 0 0 0 0 0
这人的代码输出了非常搞笑的一幕
都不用我去调整if右下上左的顺序。POJ真是垃圾的可以!!
我给他改完代码才是真正AC了
AC代码:
1 #include <iostream> 2 #include <string.h> 3 using namespace std; 4 int mp[5][5];//原始地图 5 int vis[5][5];//路径(染色) 6 int dx[25];//输出路径 7 int dy[25]; 8 void dfs(int i,int j)//这人的思路不错,通法,我就继续着他这个写,而没到(5,5)就return,而是记录所有的,到时候换个坐标为终点依旧可以输出,没把step放到参数里 9 { 10 if(mp[i][j]==1 || i<0 || j>4 || i>4 || j<0) 11 return; 12 mp[i][j]=1; 13 if(!mp[i-1][j] && i-1>=0 && i-1<5)//向上 14 { 15 if(vis[i-1][j]>vis[i][j]+1) 16 vis[i-1][j]=vis[i][j]+1; 17 dfs(i-1,j); 18 mp[i-1][j]=0; 19 } 20 if(!mp[i+1][j] && i+1>=0 && i+1<5)//向下 21 { 22 if(vis[i+1][j]>vis[i][j]+1) 23 vis[i+1][j]=vis[i][j]+1; 24 dfs(i+1,j); 25 mp[i+1][j]=0; 26 } 27 if(!mp[i][j-1] && j-1>=0 && j-1<5)//向左 28 { 29 if(vis[i][j-1]>vis[i][j]+1) 30 vis[i][j-1]=vis[i][j]+1; 31 dfs(i,j-1); 32 mp[i][j-1]=0; 33 } 34 if(!mp[i][j+1] && j+1>=0 && j+1<5)//向右 35 { 36 if(vis[i][j+1]>vis[i][j]+1) 37 vis[i][j+1]=vis[i][j]+1; 38 dfs(i,j+1); 39 mp[i][j+1]=0; 40 } 41 mp[i][j]=0; 42 } 43 int main() 44 { 45 // memset(vis,26,sizeof(vis));//5*5的地图,最多就走25步,定义个26铁定最大的,待会比较直接被取代 46 for(int i=0;i<5;i++) 47 for(int j=0;j<5;j++) 48 vis[i][j]=26; 49 memset(mp,0,sizeof(mp)); 50 for(int i=0; i<5; i++) 51 for(int j=0; j<5; j++) 52 cin >> mp[i][j]; 53 54 vis[0][0]=1; 55 dfs(0,0); 56 57 int g=vis[4][4]; 58 int x=4; 59 int y=4; 60 dx[g]=x; 61 dy[g]=y; 62 while(g>0)//按步数从大到小输出 63 { 64 g--; 65 if(vis[x-1][y]==g) 66 { 67 dx[g]=x-1; 68 dy[g]=y; 69 x--; 70 } 71 else if(vis[x+1][y]==g) 72 { 73 dx[g]=x+1; 74 dy[g]=y; 75 x++; 76 } 77 else if(vis[x][y+1]==g) 78 { 79 dx[g]=x; 80 dy[g]=y+1; 81 y++; 82 } 83 else if(vis[x][y-1]==g) 84 { 85 dx[g]=x; 86 dy[g]=y-1; 87 y--; 88 } 89 } 90 for(int i=1; i<=vis[4][4]; i++) 91 cout << "(" << dx[i] << "," << " " <<dy[i] << ")" << endl; 92 }
再看另一个人的博客,受益匪浅。可以当作BFS打印路径的模版
收获一:很棒的初始化,可以不用定义的时候初始化,可以直接 now.s=""; ,这是C语言字符数组所没有的,这样直接报错上面说过
收获二: int len=s.length(); ,能获取真实长度而不是C语言字符数组一样len给你返回个初试定义的最大长度
收获三:地图数据的多组输入,地图我一直不知道怎么多组输入,只能先单独输入第一个数据),发现是EOF退出,不是的话,再把这个值覆将要输入的5行5列数组的第一个值,然后再接着输入。这人的多组输入学到了!!
需要注意的是:
关于头文件:只需要iostream和using命名空间 参考博客
关于输入:参考博客
关于输出:string输出不能用%s会乱码,要用cout,如果printf输出就用.c_str()转换一下,这个函数先用着,具体后面再说: string aaa="sdf"; printf("%s\n",aaa.c_str());
但报了警告, warning: control reaches end of non-void function [-Wreturn-type] ,看代码发现没有return,出于好奇在 void print(string s) 里第一句就输出了s,发现正好是想要的路径,但编译器咋知道bfs传递的会是这个。于是在BFS函数最后一行加了个 cout << nex.s; return nex.s; (后来发现这样返回的不是(4,4)的s路径),但奇怪的是为啥什么都不输出?
1 #include<stdio.h> 2 int a=3; 3 void f() 4 { 5 while(a--){ 6 printf("%d\n",a); 7 if(a+1==2) 8 return;//输出21,跳出函数 9 // break;//输出21#,跳出循环 10 } 11 printf("#"); 12 } 13 int main() 14 { 15 f(); 16 } 17 18 //看oier博客,“现在是一名脑袋空空的医学生啦”
深搜递归return是返回上一个函数循环,而不是出DFS函数
广搜队列这个break是直接跳出整个循环,执行函数下面的
之前return和break全是凭感觉稀里糊涂的用
那现在来看加那两句确实不应该有输出,因为之前return了 return now.s; ,但为啥还报警告呢?尝试在函数最后加一个return “afvsz”就没警告了,尽管发现这个return没有任何作用是随便return的string值,但也可以AC。难道return必须在函数最后加上??
加了句break,并讲return放在了最后,也是AC的
1 #include<cstdio> 2 #include<iostream> 3 #include<queue> 4 #include<string> 5 #include<cstring> 6 using namespace std; 7 int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0}; //右左下上 8 int vis[5][5]; 9 int pic[5][5]; 10 struct node 11 { 12 int x, y; 13 string s; 14 15 }; 16 node now, nex; 17 int read() 18 { 19 for(int i = 0; i < 5; i++) 20 for(int j = 0; j < 5; j++) 21 if(scanf("%d", &pic[i][j]) == EOF) return 0; 22 return 1; 23 } 24 string bfs(){ 25 queue<node>q; 26 now.x = 0;now.y = 0;now.s = ""; 27 vis[0][0] = 1; 28 q.push(now); 29 while(!q.empty()) 30 { 31 now = q.front(); 32 q.pop(); 33 if(now.x == 4 && now.y == 4) 34 break; 35 36 for(int i = 0; i < 4; i++) 37 { 38 nex.x = now.x + dir[i][0]; 39 nex.y = now.y + dir[i][1]; 40 if(nex.x >= 0 && nex.x < 5 && nex.y >= 0 && nex.y < 5 && !vis[nex.x][nex.y] && pic[nex.x][nex.y] == 0) 41 { 42 vis[nex.x][nex.y] = 1; 43 switch(i){ 44 case 0:nex.s = now.s + '0';break; 45 case 1:nex.s = now.s + '1';break; 46 case 2:nex.s = now.s + '2';break; 47 case 3:nex.s = now.s + '3';break; 48 } 49 q.push(nex); 50 } 51 } 52 } 53 return now.s; 54 } 55 void print(string s) //打印路径 56 { 57 // cout << s << endl; 58 59 int len = s.length(); 60 int x = 0, y = 0; 61 printf("(%d, %d)\n", x, y); 62 for(int i = 0; i < len; i++) 63 { 64 x = x + dir[s[i] - '0'][0]; 65 y = y + dir[s[i] - '0'][1]; 66 printf("(%d, %d)\n", x, y); 67 } 68 69 } 70 int main() 71 { 72 73 while(read()) 74 { 75 memset(vis, 0, sizeof(vis)); 76 print(bfs()); 77 } 78 }
这奇怪了,为啥非要放最后呢??
先搁置
突然想到哈理工哈工大北邮研究生都手把手有教过复试代码考试,
他们研究生就北邮挺强,但北邮初试手写代码真的那些老师能看懂嘛?
这种代码一个数字就容易出错保证看的是对的吗,曾经那些acm圈的人,
岛娘老师叉姐guxiaoxu,liangzhien,都隐退了,
现在什么吴师兄公子龙各种公众号都不知道是什么时候冒出来的臭鱼烂虾,
打比赛的时候他们都不知道在哪,北邮纸盒考研才研究队列,
北邮群各种经验贴,实习被辞退什么的,不过他们工资好像真的比acm那些人高,
难道我的强项是这是他们弱项,且他们弱项都比我强
岛娘:一定要把算法竞赛好好学一遍,不知道为什么但肯定有用
岛娘:抱着电脑在xx屋檐下坐在台阶上借着wifi信号打CF,下着雨,雨水打在屏幕上,用电脑风扇取暖,A掉一个题多开心
楼教主一人干队伍被禁赛
知乎借给岛,小弹钱
邝斌:人一我十,人百我千
clj军训累了切几个题
北邮三连跳
克拉丽丝给q神酒店讲题图片
第四范式戴牛给女实习生蹲着写代码 (黑哥宾馆 王超吃饭 自豪?)
曾经...
梁芝恩
赵婧怡
又看另一个人的博客,非常好的一个思路,打印的时候用到了递归
这些只是先做为思路拓展,不自己写出来永远无法深刻理解并自己AC掉
这人会这么多高科技,map容器啥的链表啥的,结果啥都不深入,这题都写不出来,有个JB用,垃圾
非常不错的博客,思路是存前驱节点+递归输出,也算一个BFS路径输出的模版吧
以上至此都是最朴素的代码,没啥高难算法,基本都是手写底层逻辑,手写数组模拟队列什么的,强迫症不手写一遍底层就坚决不会用现成的东西
且这四道简单题耗了这么久,感觉总算全方位的精进了一些,理解更深刻了