这道题前前后后拖了好久,大概有两个周的时间,才在今天把它敲了出来。
有些题目,你只是去想,可能真的就想不出来了。所以如果实在不好想,那就上机敲敲试试吧~
当你的思路达不到这道题目的深度的时候,你可能真的没有办法完全想清楚一道题前前后后的过程,有个大概的很模糊的方向, 想去敲又不知道敲不敲的出来。这个时候就应该去试试,先把自己有思路有方法的一部分敲出来。一方面可以集中精力想接下来的步骤,另一方面,敲下来的过程其实也是从头到尾让程序在自己脑海里留下了一个较完整的印象,对于后面的思路具有启发作用。
另一个可能你本来就想复杂了,敲着敲着,也许你就会发现已经敲出来了。
第一次看这道题的时候,直到遇见了一道好题,可因为刚开始做迷宫的题目,只能处理一些常规的题目,可是很明显这道题目非常规。完全没有解题的思路。吓呆了。。直接就放弃了。
后来去网上看了一眼别人的思路。然后开始自己画图,开始找方法。不过考虑到那么多种情况,没有信心敲出来,就又放下了这道题目。
今天闲来无事,最近又做了几道图论里面的题目,自己就感觉应该差不多,没有想太多就按照原来的思路敲代码,然后敲出来,有错误,wrong 2 次,然后AC。
思路:将 "\"和"/"看成是占据了3*3的方块空间。然后按照正常走迷宫的方式遍历。不多说。
现在又敲了一遍,细心点就可以一次AC,不然又要花一些时间来调试代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> int w,h; int flag; int cnt,num,max; int vis[255][255]; int a[255][255]; char s[80][80]; void init() { memset(vis,0,sizeof(vis)); memset(a,0,sizeof(a)); cnt=num=max=0; } void transform_() { for(int i=0;i<h;i++) { for(int j=0;j<w;j++) { if(s[i][j]=='/') { a[(i+1)*3-0][(j+1)*3-2]=1; a[(i+1)*3-1][(j+1)*3-1]=1; a[(i+1)*3-2][(j+1)*3-0]=1; } else { a[(i+1)*3-2][(j+1)*3-2]=1; a[(i+1)*3-1][(j+1)*3-1]=1; a[(i+1)*3-0][(j+1)*3-0]=1; } } } for(int i=0;i<=h*3+1;i++) { a[i][0]=2; a[i][w*3+1]=2; } for(int i=0;i<=w*3+1;i++) { a[0][i]=2; a[h*3+1][i]=2; } /*for(int i=0;i<=3*h+1;i++) { for(int j=0;j<=3*w+1;j++) printf("%d",a[i][j]); printf("\n"); }*/ } void dfs(int x,int y) { if(a[x][y]==2){flag=0;return;} if(vis[x][y]||a[x][y]==1) {return;} vis[x][y]=1; num++; dfs(x-1,y); dfs(x,y-1); dfs(x,y+1); dfs(x+1,y); } int main() { int k=0; while(scanf("%d%d",&w,&h)!=EOF) { if(w==0&&h==0) break; init(); for(int i=0;i<h;i++) { scanf("%s",s[i]); } /*for(int i=0;i<h;i++) printf("%s\n",s[i]);*/ transform_(); int flag1=0; for(int i=1;i<=h*3;i++) { for(int j=1;j<=w*3;j++) { flag=1;num=0; if(!vis[i][j]&&!a[i][j]) { dfs(i,j); if(flag) { cnt++; flag1=1; if(max<num) max=num; } } } } printf("Maze #%d:\n",++k); if(flag1) { printf("%d Cycles; the longest has length %d.\n",cnt,max/3); } else printf("There are no cycles.\n"); printf("\n"); } return 0; }
不要忘记每次的初始化操作;
在写完一个步骤时,若不把握,及时检验调试(隔断输出法)。避免出现最后步骤很多不容易理清楚的情况。