深搜(DFS)模板
当N较小时考虑搜索。
DFS大致模板
//会有相对应的方向变量 例如: dx[4].dy[4]; void DFS(int x,int y) { if(满足所需要的条件) { 相应的操作;return;} else{ for(int i= ; ;) //如果是方向的话,会枚举方向 { 枚举加方向的新坐标; if(界限 :例如:不能出到地图外,有障碍,已经访问过) continue; 设置已经访问新坐标; DFS(新坐标); 恢复到未被访问; } } } int main() { // 需注意要将起点设置成已访问。 }
例题:
P1605 迷宫:
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int n,m,t; 5 int StrX,StrY; 6 int EndX,EndY; 7 int HndX,HndY; 8 int dx[4]= {1,-1,0,0}; 9 int dy[4]= {0,0,-1,1}; 10 int vis[30][30]; 11 int ans; 12 void dfs( int x, int y) //深搜 13 { 14 if(x==EndX &&y==EndY) //一定要把坐标打对!!!!! 15 { 16 ans++; 17 return ; 18 } 19 else 20 { 21 for(int i=0; i<4; i++) 22 { 23 int NewX=x+dx[i],NewY=y+dy[i]; 24 //在这道题中,没有0,0结点,所以NewX<1 NewY<1输出才正确 25 if(NewX>n || NewY>m ||NewX<1 ||NewY<1 || vis[NewX][NewY]==1 ||vis[NewX][NewY]==2) continue; 26 else 27 { 28 vis[NewX][NewY]=1; 29 dfs(NewX,NewY); 30 vis[NewX][NewY]=0; 31 } 32 } 33 } 34 35 } 36 int main() 37 { 38 scanf("%d%d%d",&n,&m,&t); 39 scanf("%d%d%d%d",&StrX,&StrY,&EndX,&EndY); 40 while(t--) 41 { 42 scanf("%d %d",&HndX,&HndY); 43 vis[HndX][HndY]=2; //将障碍设置成2, 44 } 45 vis[StrX][StrY]=1;//将起点1设置成已经访问过的状态!!!!切记 46 dfs(StrX,StrY); 47 printf("%d",ans); 48 49 return 0; 50 }
------------------------------------------------------------------------------------------------------------------------------------------------------
P1149:火柴棒等式
在这道题中,运用了回溯的思想:
过程是:先将所有的数所需要的火柴数遍历计算出来。然后在Search函数中:根据n-number[i]>=0判断是否还能减去当前火柴数。
如果可以,就将这个数的放入b[]中,载判断是否已经A,B,C,三个数都已经给你找齐,如果找齐的话,再判断是否相等,并且n是否恰好用完。
如果l还不等于3的话,在继续寻找下一个数。
最后保存其初始状态。(比较重要)
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 //使用回溯的方法 7 int n; 8 int ans; 9 int b[4];//存找到的三个数 10 int number[1112]= {6,2,5,5,4,5,6,3,7,6}; 11 void Search(int l) 12 { 13 for(int i=0; i<1112; i++) 14 { 15 16 if(n-number[i]>=0) 17 { 18 b[l]=i; 19 n=n-number[i]; 20 if(l==3) //如果符合火柴数的三个数都求出来了,然后判断 21 {if(b[1]+b[2]==b[3] && n==0) ans++;} 22 else Search(l+1); 23 n=n+number[i]; //不管l是不是等于3,都要保存之前的状态 24 //在这里要特别注意,当判断是否l==3,如果=3,判断 25 //如果!=3,再继续下一个数的搜寻。 26 } 27 } 28 } 29 int main() 30 { 31 scanf("%d",&n); 32 n=n-4; 33 for(int i=10; i<1112; i++) //注意这里是从10开始,不是从0开始。 34 { 35 number[i]=number[i/10]+number[i%10]; //在这里也需要注意,在后面三位数中,分割成一个两位数,和一位数,因为两位数,一位数已经算过了,所以就可以直接加起来 36 } 37 Search(1); 38 printf("%d",ans); 39 }
----------------------------------------------------------------------------
P1596 Lake Counting
:这道题是深搜模板题。判断连通图有多少。
1 #include <iostream> 2 #include <cstdio> 3 using namespace std; 4 int n,m,ans; 5 const int MAXN=105; 6 char map[MAXN][MAXN]; 7 8 void dfs(int x,int y) 9 { 10 for(int i=-1; i<=1; i++) 11 //在这里一共需要8个方向,循环下来加原点一共9个方向 12 { 13 for(int j=-1; j<=1; j++) 14 { 15 int NewX=x+i,NewY=y+j; 16 if(NewX>=n ||NewY>=m ||NewX<0 || NewY<0 || map[NewX][NewY]=='.') 17 continue; //判断新的坐标的错,不要打错!! 18 map[NewX][NewY]='.'; 19 dfs(NewX,NewY); 20 } 21 } 22 return; 23 } 24 int main() 25 { 26 scanf("%d%d",&n,&m); 27 for(int i=0; i<n; i++) 28 scanf("%s",map[i]); 29 for(int i=0; i<n; i++) 30 { 31 for(int j=0; j<m; j++) 32 { 33 if(map[i][j]=='W') 34 { 35 map[i][j]='.'; 36 ans++; 37 dfs(i,j); 38 } 39 } 40 } 41 printf("%d",ans); 42 return 0; 43 }
我出现的问题:
1.在判断界限时手误打错NewX NewY 和x,y;
2. 因为我读入的时候是从下标0开始的,所以在判断界限时应该是NewX>=n 时就已经越界了;
3.之前一直写成4个方向。在这里是8个方向。
------------------------------------------------------------------------------------------------------------------------------
P1219八皇后
采用DFS
#include <iostream> #include <cstdio> using namespace std; int n,a[14],l[27],r[27],ans[14],js=0; //标记是否相应位置上有皇后 void print() { for(int i=1;i<=n;i++) printf("%d ",ans[i]); cout<<endl; } void dfs(int i) { if(i>n) { js++; if(js<=3) print(); } for(int j=1;j<=n;j++) { if(a[j]==0 && l[i+j-1]==0 &&r[i-j+n]==0) /*判断界限,当前位置,左对角线,右对角线的*/ { a[j]=1; l[i+j-1]=1; r[i-j+n]=1; ans[i]=j; dfs(i+1);
//恢复初始时的状态 a[j]=0; l[i+j-1]=0; r[i-j+n]=0; } } } int main() { scanf("%d",&n); dfs(1); printf("%d",js); }
对于这道题有几个重要的点:
1.数组大小,
2.判断左对角线和右对角线的公式
3.将答案存储在ans[]数组中
4.输出答案;
------------------------------------------------------------
P1086 花生采摘,采用贪心的方法。
这道题是将所有的可采的花生排序,然后一直找可采的最大的花生。
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int MAXN=20; 6 int map[MAXN][MAXN]; 7 int k,t,m,n,ans,u; 8 struct node 9 { 10 int x; 11 int y; 12 int time; 13 int num; 14 }Edge[400]; 15 bool cmp(node a,node b) 16 { 17 return a.num>b.num; 18 } 19 void dfs() 20 { 21 for(int i=0; i<k; i++) 22 { 23 u=Edge[i].x+1; //深度 24 if(i==0) Edge[i].time=Edge[i].x+1+1; //第一步的时间等于第一个点的深度+1;因为下标是从0开始,所以要再加1; 25 else Edge[i].time=Edge[i-1].time+abs(Edge[i].x-Edge[i-1].x) 26 +abs(Edge[i].y-Edge[i-1].y)+1; //如果不是第一步的,要算出两个点之间的移动时间,以及采摘时间,以及之前的总时间 27 if(Edge[i].time+u<=t) {ans+=Edge[i].num;} //如果采摘花生的过程中花费的时间(包括采摘,走路)加回到原点的时间=约定的时间,则加入花生数。 28 } 29 } 30 int main() 31 { 32 scanf("%d%d%d",&m,&n,&t); 33 for(int i=0; i<m; i++) 34 { 35 for(int j=0; j<n; j++) 36 { 37 scanf("%d",&map[i][j]); 38 if(map[i][j]!=0) 39 { 40 Edge[k].num=map[i][j]; 41 Edge[k].x=i; 42 Edge[k].y=j; 43 k++; 44 } 45 } 46 } 47 sort(Edge,Edge+k,cmp); 48 dfs(); 49 printf("%d",ans); 50 return 0; 51 }
原文地址:https://www.cnblogs.com/yangln/p/11833183.html
- jQuery1.3以上版本"@"的问题
- 龚宏绩:三七互娱游戏上云的现状与未来
- Android 程序打包及签名
- 韩伟:解谜腾讯游戏海量服务架构
- Message和handler传递对象
- MVC RC2中关于HtmlHelper给DropDownList设置初始选中值的问题
- 结构struct(值类型)在实际应用要注意的二点:
- 王璋:腾讯云为游戏行业提供解决方案
- 利用Reflector把"闭包"看清楚
- CSS伪类的三种写法
- 吴晓斌:"吃鸡"游戏全球多地部署架构分析
- silverlight + wcf(json格式) + sqlserver存储过程分页
- 联众收购多家公司 多枚域名齐助阵
- Android AlertDialog去除黑边白边自定义布局(转)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- php7的zval相关介绍
- Zend_string与写时复制
- php的引用类型底层解析
- Roslyn 解决 dotnet core 应用进程间引用找不到 runtimeconfig 依赖文件
- dotnet 在 UOS 国产系统上安装 dotnet sdk 的方法
- 清空Redis集群所有节点的数据工具
- php数组hashtable的巧妙设计
- php运行生命周期--模块初始化php_module_startup
- Visual Studio Code的用户设置相关
- php运行生命周期--请求初始化php_request_startup
- 如何在SAP Spartacus自定义UI里使用标准UI的上下文数据
- php运行生命周期--脚本执行阶段 php_execute
- SAP Spartacus中Angular json pipe的工作原理
- 02.Android崩溃Crash库之App崩溃分析
- mysql事务的实现原理