这是第一次全部做出来的依次练习了,有一些都是做过两遍了的,但是还是错了几回,更多时候我还是应该多注意下细节,就好像章爷笑我 的一样,像什么vis[]标记没清0,什么格式错误,还有什么题目没看清,还是的注意一下了。

地址:8.1搜索练习

Problem A POJ 2488

A Knight's Journey

题目大意就是说帮你给你个P*Q的棋盘,让马一次全部走完,每个点只能走一次,而且要按照字典序输出(这句话最坑!!!)。

这道题做过了两三次了,却老是被那句“字典序输出”给坑死。第一次看到这道题的时候,看到他说的字典序还以为是要让起点最小(虽然现在明白任何一个点作为起点都是可以到达终点的,只要里面有一条路可以遍历完),然后高高兴兴的枚举了起点,心想好简单叽里呱啦就敲完了,测试样例!过了!提交!WA了!然后就回头看代码,检查实在是无力了,在网上一搜,发现别人只用0,0,做起点就过了,马上改了提交!!!还是WA!!心力憔悴的我无力了,有重新找别人的代码,看到别人代码原来还有一小段注释

“int dir[8][2]={-2,-1,-2,1,-1,-2,-1,2,1,-2,1,2,2,-1,2,1};  /*注意此处的数组数据, 为了保证每次的探索都是 符合字典序的*/”

然后才慢慢明白什么叫字典序输出,其实就是要让每一步走的位置要是在能够遍历每个点的前提下,尽量让字典序小。大家可以慢慢体会下。

贴代码:180 KB     16 ms

  1. #include <stdio.h>
  2. #include <string.h>
  3. int vis[][];
  4.  
  5. const int d[][] = {{-,-},{-,},{-,-},{-,},{,-},{,},{,-},{,}};
  6. int m,n,num,ans[],IsFind;
  7.  
  8. void dfs(int x,int y)
  9. {
  10. if(x< || x>=m || y< || y>=n || vis[x][y] || IsFind) return ;
  11. vis[x][y] = ;
  12. ans[num++] = x*n+y;
  13. if(num == m*n){IsFind = ; return;}
  14. for(int i=;i< && !IsFind;i++)
  15. {
  16. dfs(x+d[i][], y+d[i][]);
  17. }
  18. if(!IsFind)
  19. {
  20. num--;
  21. vis[x][y]=;
  22. }
  23. }
  24.  
  25. int main()
  26. {
  27. int Case,T=;
  28. while(~scanf("%d", &Case))while(Case--)
  29. {
  30. memset(vis,,sizeof(vis));
  31. scanf("%d%d", &n, &m);
  32. IsFind = ;
  33. num=;
  34. dfs(,);
  35. printf("Scenario #%d:\n", ++T);
  36. if(!IsFind)printf("impossible");
  37. else for(int i=;i<num;i++)
  38. {
  39. printf("%c%d", ans[i]/n+'A', ans[i]%n+);
  40. }
  41. printf("\n\n");
  42. if(!Case)T=;
  43. }
  44. return ;
  45. }

Problem B Avoid The Lakes

Avoid The Lakes

简单的DFS求最大相连块  392 KB  16 ms

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <queue>
  4. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  5. using namespace std;
  6.  
  7. const int d[][] = {{-,},{,},{,-},{,}};
  8. int N,M,K;
  9. int Map[][],vis[][];
  10.  
  11. int DFS(int x,int y)
  12. {
  13. if(x< || x>=N || y< || y>=M || vis[x][y] || Map[x][y])return ;
  14. int area = ;
  15. vis[x][y] = ;
  16. for(int i=;i<;i++)
  17. {
  18. area += DFS(x+d[i][], y+d[i][]);
  19. }
  20. return area;
  21. }
  22.  
  23. int main()
  24. {
  25. while(~scanf("%d%d%d",&N,&M,&K))
  26. {
  27. memset(Map,,sizeof(Map));
  28. memset(vis,,sizeof(vis));
  29. int a,b;
  30. for(int i=;i<K;i++)
  31. {
  32. scanf("%d%d", &a,&b);
  33. Map[a-][b-] = ;
  34. }
  35. int ans = ;
  36. for(int i=;i<N;i++)
  37. {
  38. for(int j=;j<M;j++)if(!vis[i][j] && !Map[i][j])
  39. {
  40. int temp = DFS(i,j);
  41. ans = MAX(ans, temp);
  42. }
  43. }
  44. printf("%d\n", ans);
  45. }
  46. return ;
  47. }

Problem C Dungeon Master

只是将求最短距离从二维增加到三维而已,数组加一维便可以实现436 KB16 ms

  1. #include <cstdio>
  2. #include <cstring>
  3. #include <queue>
  4. using namespace std;
  5.  
  6. const int Dir[][] = {{,,},{,,-},{,,},{,-,},{,,},{-,,}};
  7. struct node
  8. {
  9. int x,y,z;
  10. int step;
  11. }Start;
  12. char Map[][][];
  13. int vis[][][];
  14. int L,R,C;
  15.  
  16. void readData()
  17. {
  18. memset(vis,,sizeof(vis));
  19. int IsFind_S=;
  20. for(int i=;i<L;i++)
  21. {
  22. for(int j=;j<R;j++)
  23. {
  24. scanf("%s",Map[i][j]);
  25. for(int k=;k<C && !IsFind_S;k++) if(Map[i][j][k] == 'S')
  26. {
  27. Start.x = i;
  28. Start.y = j;
  29. Start.z = k;
  30. vis[i][j][k] = ;
  31. Start.step = ;
  32. IsFind_S = ;
  33. }
  34. }
  35. }
  36. }
  37.  
  38. int BFS()
  39. {
  40. queue<node>q;
  41. q.push(Start);
  42. while(!q.empty())
  43. {
  44. node u = q.front();
  45. q.pop();
  46. int x = u.x, y = u.y, z = u.z;
  47. if(Map[x][y][z] == 'E')return u.step;
  48. for(int i=;i<;i++)
  49. {
  50. int nx = x + Dir[i][], ny = y + Dir[i][], nz = z + Dir[i][];
  51. if(nx>= && nx<L && ny>= && ny<R && nz>= && nz < C && Map[nx][ny][nz]!='#' && !vis[nx][ny][nz])
  52. {
  53. vis[nx][ny][nz] = ;
  54. node v;
  55. v.x = nx; v.y = ny; v.z = nz; v.step = u.step+;
  56. q.push(v);
  57. }
  58. }
  59. }
  60. return ;
  61. }
  62.  
  63. int main()
  64. {
  65. while(scanf("%d%d%d%*c", &L, &R, &C) && (L||R||C))
  66. {
  67. readData();
  68. int ans = BFS();
  69. if(!ans)printf("Trapped!\n");
  70. else printf("Escaped in %d minute(s).\n",ans);
  71. }
  72. return ;
  73. }

Problem D Sum It Up

题目意思就是说给一个T和N个数,让你求出所有的可以让N个数里面找出一些数使得他们的和为T,求所有情况

由于题目说了每给一个数,这个数就只能用一次,就是说帮你给20,20,20,那么你可以用1个,2个或者3个20,但是你只用第1个或者只用第2个这两种情况都是一样的。这样的话我们每次储存时候就不要重复的储存每个数,而是另外开一个数组保存每个不一样的数,在开一个数组保存每个数的次数。那么在DFS的时候就按照每个不同的数出现的次数,从max~0一直到他们的和为T,就打印数组

代码里还有注释:228 KB 0 ms

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <queue>
  4. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  5. using namespace std;
  6.  
  7. int ans[];
  8. int N,T,IsFind;
  9. int use[],num[],NumOfUse;//NumOdUse用来统计有多好个不同的数,Use放的是不同的数,num放的是每个不同的数出现的次数
  10. int index,k;//index表示DFS到了use[index],ans总共有k个数
  11.  
  12. void DFS(int sum)
  13. {
  14. if(sum > T)return ;//和已经大于目标值,不需要继续搜索下去了
  15. if(sum == T)//找到了就打印出来
  16. {
  17. IsFind = ;//找到了
  18. for(int i=;i<k;i++)//打印
  19. {
  20. printf("%d%c", ans[i], (i==k-)? '\n' : '+');
  21. }
  22. return ;
  23. }
  24. if(index == NumOfUse)return;//已经找到了最后一个,任然不满足,返回
  25. for(int i=num[index];i>=;i--)//对于第num[index],枚举他出现的次数
  26. {
  27. for(int j=;j<i;j++)ans[k+j] = use[index];//向ans里放入i个数
  28. index+=;k+=i;
  29. DFS(sum+use[index-]*i);
  30. index-=;k-=i;
  31. }
  32. }
  33.  
  34. int main()
  35. {
  36. while(~scanf("%d%d", &T,&N) && N)
  37. {
  38. memset(num,,sizeof(num));
  39. memset(ans,,sizeof(ans));
  40. memset(use,,sizeof(use));
  41. scanf("%d", &use[]);
  42. num[] = ;
  43. NumOfUse = ;
  44. int temp;
  45. for(int i=;i<N;i++)
  46. {
  47. scanf("%d", &temp);
  48. if(temp == use[NumOfUse-])num[NumOfUse-]++;//由于题目保证输入时非升序,所以直接与前一个比较,相同,次数加1
  49. else {use[NumOfUse] = temp; num[NumOfUse]++;NumOfUse ++;}//不同,数的个数加1
  50. }
  51. IsFind = ;
  52. printf("Sums of %d:\n",T);
  53. DFS();
  54. if(!IsFind)printf("NONE\n");
  55. }
  56. return ;
  57. }

Problem E N皇后问题

第一次,直接用白书的方法,超时

  1. #include <stdio.h>
  2. #include <string.h>
  3. int vis[][],ans,n;
  4.  
  5. void dfs(int cur)
  6. {
  7. if(cur == n){ans++;return;}
  8. for(int i=;i<n;i++)
  9. {
  10. if(!vis[][i] && !vis[][i+cur] && !vis[][cur-i+n])
  11. {
  12. vis[][i] = vis[][i+cur] = vis[][cur-i+n] = ;
  13. dfs(cur+);
  14. vis[][i] = vis[][i+cur] = vis[][cur-i+n] = ;
  15. }
  16. }
  17. }
  18.  
  19. int main()
  20. {
  21. while(~scanf("%d", &n) && n)
  22. {
  23. ans = ;
  24. memset(vis,,sizeof(vis));
  25. dfs();
  26. printf("%d\n", ans);
  27. }
  28. return ;
  29. }

第二次,听了章爷的说法,打表,没有写  if(!n)break;WA了

  1. #include <stdio.h>
  2. #include <string.h>
  3. int ans[] = {,,,,,,,,,,};
  4. int main()
  5. {
  6. int n;
  7. while(~scanf("%d", &n))
  8. {
  9. printf("%d\n",ans[n]);
  10. }
  11. return ;
  12. }

第三次,终于过了228 KB15 ms

  1. #include <stdio.h>
  2. #include <string.h>
  3. int ans[] = {,,,,,,,,,,};
  4. int main()
  5. {
  6. int n;
  7. while(~scanf("%d", &n) && n)
  8. {
  9. printf("%d\n",ans[n]);
  10. }
  11. return ;
  12. }

Problem F Basic

此题我没有加入太多想法,有思路就敲了,所以写得有些挫,代码效率也不高,基本思路就是枚举每个点是否放上一个棋子,共有2^16种情况,然后就没放上一个就标记之后不能放上的点,找出者2^16中情况中可以放得数目最多的

其实也可以直接枚举每个点,放或者不放两种情况,搜索下一个点

代码 172 KB63 ms

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <queue>
  4. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  5. using namespace std;
  6.  
  7. int N;
  8. char Map[][],vis[][];
  9. const int d[][] = {{-,},{,},{,-},{,}};
  10.  
  11. int main()
  12. {
  13. while(~scanf("%d", &N) && N)
  14. {
  15. for(int i=;i<N;i++)
  16. {
  17. scanf("%s", Map[i]);
  18. }
  19. int Max = ;
  20. for(int state = ;state < (<<(N*N));state++)
  21. {
  22. memset(vis,,sizeof(vis));
  23. int ans = ;
  24. for(int i=;i<(N*N);i++)
  25. {
  26. if(((<<i) & state) && Map[i/N][i%N]!='X' && !vis[i/N][i%N])
  27. {
  28. ans++;
  29. vis[i/N][i%N] = ;
  30. for(int k=;k<;k++)
  31. {
  32. int x = i/N +d[k][], y = i%N+d[k][];
  33. while(x>= && x<N && y>= && y<N && Map[x][y]!='X')
  34. {
  35. vis[x][y] = ;
  36. x+=d[k][]; y += d[k][];
  37. }
  38. }
  39. }
  40. }
  41. Max = MAX(Max, ans);
  42. }
  43. printf("%d\n", Max);
  44. }
  45. return ;
  46. }

Problem GAsteroids!

简单的三维BFS问题

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <queue>
  4. #define Is(a,b) (a>=0 && a<b)
  5. #define MAX(a,b) ((a) > (b) ? (a) : (b))
  6. using namespace std;
  7.  
  8. const int Dir[][] = {{,,},{-,,},{,,},{,-,},{,,},{,,-}};
  9. int vis[][][],N;
  10. struct node{int x,y,z,step;};
  11. node Start,End;
  12. char Map[][][];
  13.  
  14. int ReadData()
  15. {
  16. memset(Map, , sizeof(Map));
  17. char str[]={};
  18. scanf("%s %d%*c", str, &N);
  19. for(int i=;i<N;i++)
  20. {
  21. for(int j=;j<N;j++)
  22. {
  23. scanf("%s", Map[i][j]);
  24. }
  25. }
  26. int x,y,z;
  27. scanf("%d%d%d",&x,&y,&z);
  28. Start.x = z; Start.y = y; Start.z = x;
  29. scanf("%d%d%d",&x,&y,&z);
  30. End.x = z; End.y = y; End.z = x;
  31. scanf("%s",str);
  32. if(str[] == 'E')return ;
  33. return ;
  34. }
  35.  
  36. int BFS()
  37. {
  38. memset(vis, , sizeof(vis));
  39. queue<node>q;
  40. Start.step = ;
  41. q.push(Start);
  42. node u, v;
  43. vis[Start.x][Start.y][Start.z] = ;
  44. while(!q.empty())
  45. {
  46. u = q.front();
  47. q.pop();
  48. int x = u.x, y = u.y, z = u.z;
  49. if(x == End.x && y == End.y && z == End.z)return u.step;
  50. for(int i=;i<;i++)
  51. {
  52. int nx = x+Dir[i][], ny = y+Dir[i][], nz = z+Dir[i][];
  53. if(Is(nx,N) && Is(ny,N) && Is(nz, N) && !vis[nx][ny][nz] && Map[nx][ny][nz]!='X')
  54. {
  55. vis[nx][ny][nz] = ;
  56. v.x = nx; v.y = ny; v.z = nz;
  57. v.step = u.step+;
  58. q.push(v);
  59. }
  60. }
  61. }
  62. return -;
  63. }
  64.  
  65. int main()
  66. {
  67. while(ReadData())
  68. {
  69. int ans = BFS();
  70. if(ans == -)printf("NO ROUTE\n");
  71. else printf("%d %d\n",N,ans);
  72. }
  73. }

8.1搜索专练DFS和BFS的更多相关文章

  1. 搜索分析(DFS、BFS、递归、记忆化搜索)

    搜索分析(DFS.BFS.递归.记忆化搜索) 1.线性查找 在数组a[]={0,1,2,3,4,5,6,7,8,9,10}中查找1这个元素. (1)普通搜索方法,一个循环从0到10搜索,这里略. (2 ...

  2. [HDU 2102] A计划(搜索题,典型dfs or bfs)

    A计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  3. DFS与BFS题解:[kaungbin]带你飞 简单搜索 解题报告

    DFS and  BFS 在解题前我们还是大致讲一下dfs与bfs的.(我感觉我不会bfs) 1.DFS dfs(深度优先算法) 正如其名,dfs是相当的深度,不走到最深处绝不回头的那种. 深度优先搜 ...

  4. Clone Graph leetcode java(DFS and BFS 基础)

    题目: Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. ...

  5. 邻接表实现Dijkstra算法以及DFS与BFS算法

    //============================================================================ // Name : ListDijkstr ...

  6. 数据结构(11) -- 邻接表存储图的DFS和BFS

    /////////////////////////////////////////////////////////////// //图的邻接表表示法以及DFS和BFS //////////////// ...

  7. 图论中DFS与BFS的区别、用法、详解…

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  8. 图论中DFS与BFS的区别、用法、详解?

    DFS与BFS的区别.用法.详解? 写在最前的三点: 1.所谓图的遍历就是按照某种次序访问图的每一顶点一次仅且一次. 2.实现bfs和dfs都需要解决的一个问题就是如何存储图.一般有两种方法:邻接矩阵 ...

  9. 数据结构基础(21) --DFS与BFS

    DFS 从图中某个顶点V0 出发,访问此顶点,然后依次从V0的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和V0有路径相通的顶点都被访问到(使用堆栈). //使用邻接矩阵存储的无向图的深度 ...

随机推荐

  1. php数组排序函数

    下边提到的几个数组函数的排序有一些共性: 1 数组被作为排序函数的参数,排序以后,数组本身就发生了改变,函数的返回值为bool类型.2 函数名中出现单a表示association,含义为,在按值排序的 ...

  2. (转)gLFlush()和gLFinish()

    笔者初使用OpenGL之时,所遇到的命令不能生效的问题:比如开始想用gLClearColor来设置背景色为红色,结果执行后背景还是默认的黑色.后来查阅资料,才知道这与OpenGL的指令执行流程有关,要 ...

  3. Linux Shell编程(4): 逻辑运算符、逻辑表达式详解

    shell的逻辑运算符 涉及有以下几种类型,因此只要适当选择,可以解决我们很多复杂的判断,达到事半功倍效果. 一.逻辑运算符 逻辑卷标 表示意思 1. 关于档案与目录的侦测逻辑卷标! -f 常用!侦测 ...

  4. 【英语】Bingo口语笔记(55) - work系列

  5. oracle----sqlldr用法

    SQL*LOADER是ORACLE的数据加载工具,通常用来将操作系统文件迁移到ORACLE数据库中.SQL*LOADER是大型数据仓库选择使用的加载方法,因为它提供了最快速的途径(DIRECT,PAR ...

  6. http报头正文开头会有一个整数的问题

    HTTP/.0 200 OK (省略一些东西...) Content-type:text/html 正文内容 这是我用Arduino访问某个php得到的结果 如果我在php里头输出1000个字符或更少 ...

  7. 设置VMWARE通过桥接方式使用主机无线网卡上网(zz)

    环境:WIN7旗舰版,台式机,U盘无线上网卡. 虚拟软件:VMware9.0,虚拟系统:CentOS6.4 需要实现虚拟机以独立机形式工作和上网. 先介绍一下VMware网络设置的三种方式 1 Hos ...

  8. cocos2dx+lua中cc.EventListenerMouse:create()的bug

    今天在调试项目的时候用到了鼠标事件的监听 在创建事件监听器的时候出了问题 cc.EventListenerMouse:create() 这句返回值为nil 原来这是cocos2dx引擎的一个bug,t ...

  9. IOS设备启动图像命名规范

  10. SQL 教程学习进度备忘

    书签:跳过:另外跳过的内容有待跟进 __________________ 学习资源:W3School. _________________ 跳过的内容: 1.  “SQL select”底部的“ AD ...