DFS

  • 路径之谜
  • AcWing 842. 排列数字

路径之谜

只过2/7代码

import java.util.Scanner;public class Main {static int N = 500;static int dir[][] = {{-1,0}, {0, 1}, {1, 0}, {0, -1}}; // 上右下左static boolean vis[][] = new boolean[N][N];static int n;static int WES[] = new int[N];static int NOR[] = new int[N];public static void dfs(int u, int x, int y, int west[], int north[], int [] path){//System.out.println(u + " "+ x + " " + y);if(x == n - 1 && y == n - 1){boolean success = true;for(int i = 0; i < n; i ++){if(WES[i] != west[i] | NOR[i] != north[i]){success = false;break;}}if(success){for(int i = 0; i < u; i ++){System.out.print(path[i] + " ");}System.exit(0);}return;}for(int i = 0; i < 4; i ++){int nx = x + dir[i][0], ny = y + dir[i][1];if(nx < 0 || nx >= n || ny < 0 || ny >= n){continue;}if(!vis[nx][ny]){north[ny] += 1;west[nx] += 1;vis[nx][ny] = true;path[u] = nx  * n + ny;dfs(u + 1, nx, ny, west, north, path);north[ny] -= 1;west[nx] -= 1;vis[nx][ny] = false;}}}public static void main(String[] args) {Scanner reader = new Scanner(System.in);n = reader.nextInt();for(int i = 0; i < n; i ++){NOR[i] = reader.nextInt();}for(int i = 0; i < n; i ++){WES[i] = reader.nextInt();}int west[] = new int[N];int north[]= new int[N];int path[] = new int[N];// 注意dfs写法// 这种写法需要初始化起始点(0, 0)west[0] = 1;north[0] = 1;path[0] = 0;vis[0][0] = true;dfs(1, 0, 0, west, north, path);}
}
import java.util.Scanner;public class Main {static Scanner in=new Scanner(System.in);static int[] dx= {0,1,0,-1};static int[] dy= {1,0,-1,0};static int n=in.nextInt();static int[][] a=new int[n][n];static int[][] v=new int[n][n];static int[] b=new int[n];static int[] x=new int[n];static int[] vs=new int[n*n];
//    static int sum=0,count=0;public static void main(String[] args) {for(int i=0;i<n;i++) {b[i]=in.nextInt();
//            sum+=b[i];}for(int i=0;i<n;i++) {x[i]=in.nextInt();
//            sum+=x[i];}
//        v[0][0]=1;
//        b[0]-=1;
//        x[0]-=1;dfs(0, 0, 0);}public static void dfs(int startx,int starty,int step) {v[startx][starty]=1;vs[step]=startx*n+starty;b[starty]--;x[startx]--;
//        sum-=2;if(startx==n-1&&starty==n-1&&check()) {//            if(check())
//            if(count==28)
//                System.out.println();for(int i=0;i<=step;i++) {System.out.print(vs[i]+" ");}System.out.println();
//            count++;return;}for(int k=0;k<4;k++) {int tx=startx+dx[k],ty=starty+dy[k];if(tx>=0&&tx<n&&ty>=0&&ty<n&&v[tx][ty]!=1) {if(b[ty]>0&&x[tx]>0) {v[tx][ty]=1;dfs(tx, ty, step+1);v[tx][ty]=0;}//                sum+=2;}}b[starty]++;x[startx]++;}public static boolean check() {for(int i=0;i<n;i++) {if(b[i]!=0||x[i]!=0) {return false;}}return true;}
}

AcWing 842. 排列数字

【题目描述】

AcWing 842. 排列数字

【思路】
DFS中的经典例题
dfs(int m, String res)
res记录遍历的一条路径,到达叶子结点时也就是m == n是,就是一个排列。
vis标记数组标记该条路径中1 ~ n用过的数字,因为每一个数字只能使用一次。
要注意现场的恢复。因为第一次完成深搜后,所有元素都已经被访问过了。如果没有进行恢复现场这样在回溯到上一层时,上层的现场中的状态都被下层更改了,数据就会乱套。

import java.util.Scanner;
public class Main{static int N = 10;static int n;static boolean vis[] = new boolean[N];public static void  dfs(int m, String res){if(m == n){System.out.println(res);return;}for(int i = 1; i <= n; i ++){if( !vis[i]){vis[i] = true;dfs(m + 1, res + i + " ");vis[i] = false;}}}public static void main(String args[]){Scanner reader = new Scanner(System.in);n = reader.nextInt();dfs(0, "");}
}
```y总写法
**【思路】**
n个坑填n个数
path记录走过的路径,即排列的方案
```javaimport java.util.Scanner;
class Main{/*** u表示当前所在层数 u == 0表示当前层数为1 要填第0个坑*/static int N = 10;static int n;static int path[] = new int[N];static boolean st[] = new boolean[N];public static void dfs(int u){if(u == n){//到达叶子结点,也就是填完了最后一个坑 要填第n个坑 for(int i = 0; i < n; i ++)System.out.print(path[i]+" ");System.out.println();}//枚举每个坑应该填哪些数字for(int i = 1; i <= n; i ++)if( !st[i]){st[i] = true;path[u] = i; //第u个坑填idfs( u + 1);st[i] = false; //回复现场}}public static void main(String args[]){Scanner reader = new Scanner(System.in);n = reader.nextInt();dfs(0);}
}
```## AcWing 843. n-皇后问题 **【题目描述】**
[AcWing 843. n-皇后问题  ](https://www.acwing.com/problem/content/845/)**【思路】**
cols[]标记数组标记哪些列被用过了
queens[i]存放第i个皇后放在哪一列了
发生对角线冲突的点横纵坐标之差相等
时间复杂度O(n! * n^2)
```java
import java.util.Scanner;
import java.lang.Math;
public class Main{static int  N = 10;static char[][] g = new char[N][N];static boolean[]cols = new boolean[N];static int queens[] = new int[N];//保存每一行皇后的位置static int n;//检查对角线是否冲突public static boolean check(int x, int y){for(int i = 0; i < x; i ++)if( Math.abs(y -queens[i]) == Math.abs(x - i) )return false;return true;}public static void dfs(int x){//排列最后一行的皇后if(x == n){for(int i = 0; i < n; i ++){for(int j = 0; j < n; j ++)System.out.print(g[i][j]+"");System.out.println();}System.out.println();   return;}//选择合适列for(int i = 0; i < n; i ++){//(x, i)if(!cols[i] && check(x, i)){cols[i] = true;g[x][i] = 'Q';queens[x] = i;dfs(x + 1);g[x][i] = '.';cols[i] = false;}}}public static void main(String args[]){Scanner reader = new Scanner(System.in);n = reader.nextInt();for(int i = 0; i < N; i ++)for(int j = 0; j < N; j ++)g[i][j] = '.';dfs(0);}
}
```y总写法, 两条对角线根据斜截式算得为c1 =x + y,c2 = y - x + n
对问题进行抽象,按行枚举,每一行只能放皇后 即每一行就是一个坑。n个皇后填n个空
然后枚举该行的皇后可以放在哪一列
```java
/*
n个皇后填n个空
*/import java.util.Scanner;
import java.util.Arrays;class Main{static int N = 10;static int n;static boolean cols[] = new boolean[N];static boolean dg[] = new boolean[2 * N];static boolean udg[] = new boolean[2 * N];static char[][] g= new char[N][N];public static void dfs(int x){if( x == n){ //到叶子结点 表示摆放好了最后一个皇后for(int i = 0; i < n; i ++){for(int j = 0; j < n; j ++)System.out.print(g[i][j]);System.out.println();}System.out.println();return;}//枚举第x个(第x行)皇后可以放置的位置for(int y = 0; y < n; y++)if( !cols[y] && !dg[x + y] && !udg[y - x + n]){g[x][y] = 'Q';cols[y] = true;dg[x + y] = true;udg[y - x + n] = true;dfs( x + 1); //摆列下一行的皇后g[x][y] = '.';cols[y] = false;dg[x + y] = false;udg[y - x + n] = false;}}public static void main(String args[]){Scanner reader = new Scanner(System.in);n = reader.nextInt();for(int i = 0; i < n; i ++)Arrays.fill(g[i],'.');dfs(0);}
}
```**【思路】**
按格子进行搜索
时间复杂度O(2 ^ (n^2))
```javaimport java.util.Scanner;
import java.util.Arrays;class Main{static int N = 10;static int n;static boolean cols[] = new boolean[N];static boolean rows[] = new boolean[N];static boolean dg[] = new boolean[2 * N];static boolean udg[] = new boolean[2 * N];static char[][] g= new char[N][N];public static void dfs(int x, int y, int s){if(y == n){//搜索下一行x ++;y = 0;}if(x == n){if( s == n){for(int i = 0; i < n; i ++){for(int j = 0; j < n; j++)System.out.print(g[i][j]);System.out.println();}System.out.println();}return;}//该格子不放皇后dfs(x, y + 1, s);//该格子放皇后if( !rows[x] && !cols[y] && !dg[x + y] && !udg[y - x + n]){g[x][y] = 'Q';rows[x] = true;cols[y] = true;dg[x + y] = true;udg[y - x + n] = true;dfs(x, y + 1, s + 1);g[x][y] = '.';rows[x] = false;cols[y] = false;dg[x + y] = false;udg[y - x + n] = false;}}public static void main(String args[]){Scanner reader = new Scanner(System.in);n = reader.nextInt();for(int i = 0; i < n; i ++)Arrays.fill(g[i],'.');dfs(0, 0, 0);}
}
```# 记忆化搜索# AcWing 901. 滑雪 **【题目描述】**![在这里插入图片描述](https://img-blog.csdnimg.cn/2021041300031812.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg1NTkwNw==,size_16,color_FFFFFF,t_70)
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210413000330842.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80NDg1NTkwNw==,size_16,color_FFFFFF,t_70)[AcWing 901. 滑雪 ](https://www.acwing.com/problem/content/903/)```java
import java.util.Scanner;
import java.util.Arrays;
public class Main{static int N = 310;static int R, C;static int h[][] = new int[N][N];static int f[][] = new int[N][N]; //f[i][j] 表示在(i,j)点最长滑雪长度static int dir[][] = { {-1, 0}, {0, 1}, {1, 0}, {0, - 1}};public static int dfs(int x, int y){//计算前先查询if( f[x][y] != -1) return f[x][y];//至少可以是该点自己f[x][y] = 1;for(int i = 0; i < 4; i ++){int a = x + dir[i][0], b = y + dir[i][1];//四种滑法取最大值if( a >= 0 && a < R && b >= 0 && b < C && h[a][b] < h[x][y]){f[x][y] = Math.max(f[x][y] ,dfs(a, b) + 1);}}return f[x][y];}public static void main(String args[]){Scanner reader = new Scanner(System.in);R = reader.nextInt();C = reader.nextInt();for(int i = 0; i < R; i ++)for(int j = 0; j < C; j ++)h[i][j] = reader.nextInt();//初始化for(int i = 0; i < R; i ++) Arrays.fill(f[i], - 1);int ans = 0;//每一个起点for(int i = 0; i < R; i ++)for(int j = 0; j < C; j ++){ans = Math.max( ans, dfs(i, j) );}System.out.println(ans);}
}
```# 地宫取宝
**【题目描述】**X 国王有一个地宫宝库。是 n x m 个格子的矩阵。每个格子放一件宝贝。每个宝贝贴着价值标签。地宫的入口在左上角,出口在右下角。小明被带到地宫的入口,国王要求他只能向右或向下行走。走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。当小明走到出口时,如果他手中的宝贝恰好是k件,则这些宝贝就可以送给小明。请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这k件宝贝。【数据格式】输入一行3个整数,用空格分开:n m k (1<=n,m<=50, 1<=k<=12)接下来有 n 行数据,每行有 m 个整数 Ci (0<=Ci<=12)代表这个格子上的宝物的价值要求输出一个整数,表示正好取k个宝贝的行动方案数。该数字可能很大,输出它对 1000000007 取模的结果。例如,输入:
2 2 2
1 2
2 1
程序应该输出:
2再例如,输入:
2 3 2
1 2 3
2 1 5
程序应该输出:
14 ```java
package 第五届;import java.util.Scanner;public class t09_地宫取宝_记忆dfs  {static int [][] map;static int n,m,k;static long [][][][] memo=new long [51][51][14][13];static final long mod=1000000007;public static long dfs(int x,int y,int max,int cnt) {if(x>=n||y>=m||cnt>k)return 0;//计算前先查询if(memo[x][y][max+1][cnt]!=-1) {return memo[x][y][max+1][cnt];}int cur=map[x][y];long ans=0;if(x==n-1&&y==m-1) {if(cnt==k||(cnt==k-1&&cur>max)) {ans++;}return ans%=mod;}if(cur>max) {//大于才可能选ans+=dfs(x+1,y,cur,cnt+1);ans+=dfs(x,y+1,cur,cnt+1);}//不论大于不大都不选ans+=dfs(x+1,y,max,cnt);ans+=dfs(x,y+1,max,cnt);memo[x][y][max+1][cnt]=ans%mod;return memo[x][y][max+1][cnt];}public static void main(String[] args) {Scanner reader=new Scanner(System.in);while(true) {n=reader.nextInt();m=reader.nextInt();k=reader.nextInt();map=new int[n][m];for (int i = 0; i < n; i++) {for (int j = 0; j < m; j++) {map[i][j]=reader.nextInt();}}//初始化记忆数组for (int i = 0; i < 51; i++) {for (int j = 0; j <51; j++) {for (int k = 0; k < 14; k++) {for (int p = 0; p < 13; p++) {memo[i][j][k][p]=-1;}}}}System.out.println(dfs(0,0,-1,0));}}}```## 砝码称重
[3417. 砝码称重](https://www.acwing.com/problem/content/description/3420/)爆搜过一半样例```java
import java.util.Scanner;
class Main{static int N = 110, ans = 0, M = 100010;static int n;static int w[] = new int[N];static boolean st[] = new boolean[M];public static void dfs(int u, int sum){if(u == n){ // n个砝码都选完了if(sum > 0 && !st[sum]){st[sum] = true;ans ++;}return;}dfs(u + 1, sum - w[u]); // 当前选砝码w[u]放天平左边dfs(u + 1, sum); // 当前不选砝码dfs(u + 1, sum + w[u]); // 当前选砝码w[u]放天平右边}public static void main(String args[]){Scanner reader = new Scanner(System.in);n = reader.nextInt();int m = 0; // 最大正整数重量for(int i = 0; i < n; i ++){w[i] = reader.nextInt();m += w[i];}dfs(0, 0);System.out.println(ans);}
}
```

基础算法模板题(五)—— DFS相关推荐

  1. 蓝桥杯之算法模板题 Python版

    蓝桥杯之算法模板题 Python版 文章目录 蓝桥杯之算法模板题 Python版 线段树 DP 动态规划 dp, LIS ** 01背包 完全背包 多重背包 混合背包 分组背包 区间DP 一.什么是区 ...

  2. HDU 2389 Rain on your Parade(二分匹配+Hopcroft-Carp算法模板题)

    You're giving a party in the garden of your villa by the sea. The party is a huge success, and every ...

  3. kuangbin 最小生成树专题 - ZOJ - 1586 QS Network (朴素 Prim算法 模板题)

    kuangbin 最小生成树专题 - ZOJ - 1586 QS Network (朴素 Prim算法 模板题) 总题单 week 3 [kuangbin带你飞] 题单 最小生成树 + 线段树 Cli ...

  4. 基础算法模板——高精度运算

    基础算法模板--高精度运算 1. 高精度加法 vector<int> add(vector<int> &A, vector<int> &B) {if ...

  5. 2020最新-精选基础算法100题(面试必备)

    0x01.概述 作为一个程序员,算法能力必不可少,虽然不一定是算法工程师,但是算法还是彰显着个人的编码能力,面试中也经常会被问到,甚至会被要求临场做算法题,所以,还是好好积累吧. 个人其实对算法挺有兴 ...

  6. 【蓝桥杯算法模板题--蓝桥题库Java】

    PDF下载地址:点击即可 文章目录 ==算法模板== 1 排序(ArrayList,sort) 题目描述 输入描述 输出描述 输入输出样例 示例 1 运行限制 2 小明的彩灯(差分) 输入输出样例 示 ...

  7. CSP认证201509-4 高速公路[C++题解]:强连通分量、tarjan算法模板题

    题目分析 来源:acwing 分析: 所求即为强连通分量的个数,然后计算每个强连通分量中点的个数,相加即可. 所谓强连通分量,它是一个子图,其中任意两点可以相互到达,并且再加一个点,就不能满足任意两点 ...

  8. 数据结构和算法笔记(2)基础算法模板

    有很多的基础算法经常会用到,但是又容易写错.而网上查到的实现又五花八门.良莠不齐,故在此整理记录. 本文的目录如下: 1.二分查找    2.并查集    3.最大公约数    4.Trie树(前缀树 ...

  9. [AcWing算法刷题]之DFS+BFS迷宫模板(简单)

    题目来源: 题库 - AcWing 目录 DFS和BFS模板题目:迷宫类 机器人的运动范围​ 字母 迷宫 红与黑 棋盘问题 马走日 全球变暖 DFS综合类 乘积最大(提高课) 单词接龙(提高课) 取石 ...

  10. Java基础算法50题(一)

    文章目录 1.有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 2.判断101-200之间有多少个素数,并输出所有素 ...

最新文章

  1. python列表解析式_Python基础入门-列表解析式
  2. DI(依赖注入)简单理解 NO1
  3. 【数论想法题】小C的问题 @科林明伦杯哈尔滨理工大学第八届程序设计竞赛...
  4. LeetCode 743. 网络延迟时间(最短路径)
  5. matlab画转体_【求助】matlab生成旋转体?
  6. nodejs笔记之流(stream)
  7. Oracle PLSQL Demo - 04.数字FOR LOOP循环[NUMBERABLE (FOR) LOOP]
  8. 通过web的方式动态查看tomcat的catalina.out的日志(web.py)
  9. 几道Java基础面试题
  10. vb.net它SqlHelper制备及应用
  11. oracle dba (适用,OracleDBA笔试题
  12. 内存管理之直接内存管理
  13. 事务(进程 ID )与另一个进程已被死锁在 lock 资源上,且该事务已被选作死锁牺牲品...
  14. (转载)高光谱数据读取by multibandread函数
  15. python的基础操作_python列表基础操作
  16. 学李炎恢老师的PHP第一季 笔记 多用户留言系统-TestGuest0.2
  17. echarts省市区id(区域编码)实现地图下钻点击(data赋值自定义属性值,geojson信息获取)
  18. 圣科车衣,给予您的爱车完美守护
  19. SharePoint重置密码功能Demo
  20. Cocos Creator Layout组件

热门文章

  1. proteus 8.9 8.6 串口 无法仿真 仿真不出来 51单片机
  2. 波哥让我总结学习中遇到的ES6新增特性
  3. 17_ue4进阶末日生存游戏开发[塌陷为宏]
  4. 关于神经网络中过拟合的问题
  5. java+springmvc+vues ssm454高校信息资源共享平台#毕业设计
  6. 校园户外运动同好社区管理系统
  7. QTreeWidget Item懒加载
  8. 中国电影工业,走到了关键的十字路口!
  9. perl 报错 Can’t locate JSON.pm in @INC
  10. Cento开放服务器端口