搜索-DFS
洛谷 P1706
https://www.luogu.com.cn/problem/P1706
程序模板:
#include<bits/stdc++.h> using namespace std; //定义变量 n,当前排列记录数组,当前排列数字是否使用数组 int n,used[10],curRow[10]; void dfs(int k){ //满足退出条件 输出当前排列数组 // 1~n全部展开 for(int i=1;i<=n;i++){ //判断当前数字未使用进入 //当前数组是否使用,在定义数组是否设置 //设置 // 记录到当次排列数组 //递归dfs //恢复 } } int main(){ //输入 //调用dfs 0开始 深度优先搜索 return 0; }
洛谷 P2404
https://www.luogu.com.cn/problem/P2404
程序模板:
#include <iostream> using namespace std; //输入要拆分的自然数和当次拆分过程中产生的数 int n, a[200]; //deep dfs深度每次加1 当次拆分的自然数 7 6 void dfs(int deep, int k){ //退出条件 if(k == 0){ if(deep == 2)//只有一个数时,不拆分 return; // 1 ~ deep 循环打印 注意 +和换行 // coding return; } // 每次对k个数进行递归拆分 for(int i = a[deep-1]; i <= k; i++){ //当前数放进数组 //coding //对去除当次的数,再进行递归拆分 dfs deep+1 , k-i //coding } } int main(){ cin >> n; //从自然数1开始拆分 a[0] = 1; dfs(1, n); return 0; }
洛谷 P1605
https://www.luogu.com.cn/problem/P1605
程序模板:
#include<bits/stdc++.h> using namespace std; int n,m,coun=0,t; int sx,sy,fx,fy; int mp[6][6];//标记是否为障碍物 0为障碍物 1为无障碍物 int vis[6][6]={0};//全为没走过 int dx[4]={0, 0,1,-1}; int dy[4]={1,-1,0, 0}; int b,c;//障碍坐标数 void dfs(int x,int y){ //到达退出 退出条件x==fx && y==fy coun累加 //四个方向深度搜索 for(int i=0;i<=3;i++){ //判断mp mp[x+dx[i]][y+dy[i]]==1 是否有障碍物 vis[x+dx[i]][y+dy[i]]==0是否走过 if(mp[x+dx[i]][y+dy[i]]==1&&vis[x+dx[i]][y+dy[i]]==0){ //标记为已走过 //coding //继续深度搜索x+dx[i] ,y+dy[i] //coding //回溯一步 //coding } } } int main(){ cin>>n>>m>>t; cin>>sx>>sy>>fx>>fy; vis[sx][sy]=1;//开始位置第一步走 //所有的标记为无障碍物 mp 二维数组都为1 //coding //把障碍物标记处理 循环对应有障碍物mp位置设置为0 //coding dfs(sx,sy);//开始搜索 printf("%d",coun); return 0; }
洛谷 P1101
https://www.luogu.com.cn/problem/P1101
程序模板:
#include<bits/stdc++.h> using namespace std; const char key[8]={'y','i','z','h','o','n','g','\0'}; char s[105][105]; int n; //x y 的8个方向找 int dirx[8]={-1,-1,-1,0,0,1,1,1},diry[8]={-1,0,1,-1,1,-1,0,1}; int tx[105],ty[105];//记录当次查找每个字母依次位置,用来恢复现场 int used[105][105];//记录所有出发点 int locx,locy;//当前出发点 //回溯打标,找到单词所有字母后,把这些字母的位置都打标 void markBack(int x,int y){ while (x!=-1&&y!=-1){//如果不是这条路的则是-1,前面定义了 used[x][y]=1;//将当前坐标打上标记 x=tx[x];//回到我们是怎么走过来的,即到上一步的地方去 y=ty[y]; } } //x,y当前坐标 rank已经找到了几个 fx dfs找单词的方向 void dfs (int x,int y,int rank,int fx){ // y start找了一个 i rank=1 rank=6时 找全了 if (rank==6){ used[locx][locy]=1;//此出发点已经找完 markBack(x,y); return; } int kx,ky; kx=x+dirx[fx];ky=y+diry[fx];//临时变量,下一个坐标 if (kx<0||ky<0||kx>=n||ky>=n)//防止越界 return; if (s[kx][ky]==key[rank+1]){ tx[kx]=x;//记录下找到下一个字符的路径,表示kx是从x这来的 ty[ky]=y; dfs(kx,ky,rank+1,fx);//进行下一步搜索 tx[kx]=ty[ky]=-1;//把路径恢复 } } //从y的位置开始 往8个方向查找 void start (int x,int y){//最开始找到的'y'的坐标 int kx,ky,k;//临时坐标 for (k=0;k<8;k++){ kx=x+dirx[k];ky=y+diry[k];//各个方向都进行查找 if (kx<0||ky<0||kx>=n||ky>=n)//不能越界 continue; if (s[kx][ky]==key[1]){//如果找到了在方向上有'i'就往这个方向继续查找 locx=x;//先记录下我们的出发点 locy=y; dfs (kx,ky,1,k); } } } // 输出 used 字母打过标,说明用过,否则输出 * void print (void){ //循环输出used数组 打标的原样输出,否则输出 * } int main (){ cin>>n;//输入n memset(tx,-1,sizeof(tx));//将每个路径都记为-1 memset(ty,-1,sizeof(ty)); for (int i=0;i<n;i++) for (int j=0;j<n;j++) cin>>s[i][j]; for (int i=0;i<n;i++) for (int j=0;j<n;j++) if (s[i][j]==key[0])//如果找到了符合条件的开头字符'y' start(i,j);//先进行处理 print();//输出 return 0; }
子集和
http://iai.sh.cn/problem/476
#include<bits/stdc++.h> using namespace std; int a[30]; int sum = 0,n,t,ans;//n为集合的大小,t为目标值 void dfs(int step){ if (step == n){//递归n个数 if (sum == t){//sum和目标值相同 一次方案 ans++; return; } }else{ sum += a[step]; dfs(step + 1);//取当前值计算一次 sum -= a[step];//回溯时先还原 dfs(step + 1);//不取当前值计算一次 } } int main(){ cin>>n>>t; for (int i = 0; i < n; i++) cin>>a[i]; dfs(0);//从第一个数开始取 if(ans>0){ cout<<"Yes"; }else{ cout<<"No"; } return 0; }
四方定理
http://iai.sh.cn/problem/477
#include<bits/stdc++.h> using namespace std; typedef long long LL; LL n; const int maxC=5e4+10; LL ans[maxC]; //step 深度几个数 //sum 几个数的和 void dfs(LL step, LL sum){ if (step>4){//深度4以后 保证有四个数相加 if (sum==n){//四个数的和等于n for (LL i=1; i<=4; i++){//输出这四个数 cout<<ans[i]<<" "; } cout<<"\n"; } return ; } for (LL i=0; i*i<=n; i++){ if (ans[step-1]<=i){//前一个数必须小于等于当前数 ans[step]=i;//当前数记录到数组 dfs(step+1,sum+i*i);//递归下一个数 总和加上当前数 } } } int main(){ cin>>n; dfs(1,0);//第一个数 此时和为0 return 0; }
八皇后
noi 1700 输出 八皇后问题
输出第几个八皇后
迷宫-是否可以到底某个坐标
红与黑-计算可到达的瓷砖数
棋盘问题
马走日
放苹果
作者:newcode 更多资源请关注纽扣编程微信公众号
从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习