【dfs】【回溯】【深度优先遍历】【蓝桥杯】

1.2019年 蓝桥杯A组 java省赛 试题 I: 糖果

import java.util.Scanner;

public class _9糖果 {

	static int min=(int) 1e+100;
	static int suger[][]= new int [102][4];
	static int n,m,k;
	//visitsuger表示当前这种口味的糖有没有被访问,共m种口味
	static int visitsuger[]=new int [102];
	//visit[]表示当前这包糖有没有被访问,也可以理解要不要当前这包糖
	static boolean visit[]=new boolean [102];
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		
		n=in.nextInt();
		m=in.nextInt();
		k=in.nextInt();
		
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<k;j++)
			{
				suger[i][j]=in.nextInt();
			}
		}
		dfs(0,0);
		System.out.println(min);

	}
	static boolean check()
	{
		for( int i=1;i<=m;i++)
		{
			if(visitsuger[i]==0)
				return false;
		}
		return true;
	}
	
	static void dfs(int i,int res)
	{
		//i是从0开始的,所以是i>=n
		if(i>=n)
		{
			if(check())
			{
				if(res<min)
					min=res;
				
			}
			return;
		}
		
		//要第i包糖
		visit[i]=true;
		for(int j=0;j<k;j++)
		{
			visitsuger[suger[i][j]]++;//这包糖里的口味都算一下
		}
		dfs(i+1,res+1);//检查下一包糖,并且包数+1
		
		//不要这包糖
		visit[i]=false;
		for(int j=0;j<k;j++)
		{
			visitsuger[suger[i][j]]--;//把刚才的那个++给减掉
		}
		dfs(i+1,res); //检查下一包糖
	}
}

2.蓝桥杯 全球变暖

package dfs续;

import java.util.Scanner;

public class _1全球变暖 {
	static int n;
	static boolean visit[] [ ]= new boolean [100][100];
	static char mapp[][]=new char[100][100];
	static int insland []=new int [100001];
	
	static void dfs(int i,int j,int k )
	{
		if(i<1||j<1||i>n-2||j>n-2)
		{
			return;
		}
		if(mapp[i][j]=='.')
			return;
		if(visit[i][j]==true)
			return;
		visit[i][j]=true;
		if(mapp[i-1][j]=='#'&&mapp[i+1][j]=='#'&&mapp[i][j-1]=='#'&&mapp[i][j+1]=='#'&&mapp[i][j]=='#')
		{
			insland[k]++;//第k个岛屿有几个不可淹没点
		}
		dfs(i-1,j,k);
		dfs(i+1,j,k);
		dfs(i,j-1,k);
		dfs(i,j+1,k);

	}
	public static void main(String[] args) {
		  Scanner in=new Scanner(System.in);
		  int k=0,res=0;
	      n = in.nextInt();
	      String temp=in.nextLine();//读取空格?
	        //地图储存
	      for (int i = 0; i < n; i++) {
	            String line = in.nextLine();
	            mapp[i] = line.toCharArray();
	        }
	      for( int i=1;i<=n-2;i++)
	      {
	    	  for(int j=1;j<=n-2;j++)
	    	  {
	    		  
	    		  if(mapp[i][j]=='#'&&visit[i][j]==false)
	    		  {
	    			  k++;
	    			  dfs(i,j,k);
	    		  } 
	    	  }
	      }
	      for(int i=1;i<=k;i++)
	      {
	    	  if(insland[i]==0)
	    		  res++;
	      }
	      System.out.print(res);
	}
}

3.方格填数 蓝桥杯

package dfs续;

public class _2方格填数 {
	
	public static int count;
	public static int[][] map = new int[3][4];
	public static int[] visited = new int[10];
	// 矩阵大小
	public static int m = map.length;
	public static int n = map[0].length;
	
	// 为了减少网页上代码行数,这里就用大佬写的代码了
	// 如果看不懂,请自行替换为我那种八个坐标挨个判断的原始方法
	public static int dir[][] = new int[][]{
				{0, -1}, 
				{-1, -1}, 
				{-1, 0}, 
				{-1, 1}
	};
	
	public static boolean checked(int x, int y, int num) {
		for (int i = 0; i < 4; i++) {
			int nx = x + dir[i][0];
			int ny = y + dir[i][1];
			if (nx >= 0 && nx < 3 && ny >= 0 && ny < 4) {
				//相邻的点有相邻的数字
				//还没有填过数字的格子-10 肯定不会等于当前格子0-9 +1或-1
				if (map[nx][ny] == num - 1 || map[nx][ny] == num + 1) {
					return false;
				}
			}
		}
		return true;
	}
	
	public static void dfs(int x, int y) {

		if(x == m-1 && y == n-1) { // 到达出口
			count++;
	      return;
		}
		if(y >= n) { // y坐标越界
			dfs(x + 1, 0); // 换行,y从0开始
		} else {
			for(int i=0; i<=9; i++) {	
				// 搜索构建矩阵
				if(visited[i] == 0 && checked(x,y,i)) { //checked()检查(x,y)坐标周围的数与我们要填的数i的关系是否满足不连续
					visited[i] = 1;
					map[x][y] = i;
					dfs(x,y+1);
					map[x][y] = 100;
					visited[i] = 0;
				}
			}
		}
	}
	
	public static void main(String[] args) {
		for(int i=0; i<m; i++) {
			for(int j=0; j<n; j++) {
				map[i][j] = 100;
			}
		}
		dfs(0,1);
		System.out.println(count); // 答案:1580
	}
}

4.牌型总数

package dfs续;
/*小明被劫持到X赌城,被迫与其他3人玩牌。
一副扑克牌(去掉大小王牌,共52张),均匀发给4个人,每个人13张。
这时,小明脑子里突然冒出一个问题:
如果不考虑花色,只考虑点数,也不考虑自己得到的牌的先后顺序,自己手里能拿到的初始牌型组合一共有多少种呢?*/
public class _3牌型种数 {

	public static void main(String[] args) {
		dfs(1,0);
		System.out.println(res);

	}
	static int a[]=new int [14];
	static int res=0;
	
	static void dfs(int n,int cnt)
	{
		if(n==14)
		{
			if(cnt==13)
				res++;
			return;
		}
		if(n>13)
			return;
		for(int i=0;i<=4;i++)
		{
			dfs(n+1,cnt+i);
		}
	}
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
深度优先搜索(DFS)是一种常用的图遍历算法,它可以用来遍历或搜索图中的节点。在DFS中,从一个起始节点开始,沿着一条路径尽可能深入地访问节点,直到无法继续深入为止,然后回溯到上一个节点,继续访问其他未被访问的节点,直到所有节点都被访问为止。 在Java中,可以使用递归或者栈来实现DFS算法。下面是一个使用递归实现DFS的示例代码: ```java import java.util.*; class Graph { private int V; // 图中节点的数量 private LinkedList<Integer> adj[]; // 邻接表表示图 // 构造函数 Graph(int v) { V = v; adj = new LinkedList[v]; for (int i = 0; i < v; ++i) adj[i] = new LinkedList(); } // 添加边 void addEdge(int v, int w) { adj[v].add(w); } // 递归实现DFS void DFSUtil(int v, boolean visited[]) { visited[v] = true; System.out.print(v + " "); Iterator<Integer> i = adj[v].listIterator(); while (i.hasNext()) { int n = i.next(); if (!visited[n]) DFSUtil(n, visited); } } // 对外公开的DFS接口 void DFS(int v) { boolean visited[] = new boolean[V]; DFSUtil(v, visited); } } public class Main { public static void main(String args[]) { Graph g = new Graph(4); g.addEdge(0, 1); g.addEdge(0, 2); g.addEdge(1, 2); g.addEdge(2, 0); g.addEdge(2, 3); g.addEdge(3, 3); System.out.println("节点2开始的DFS遍历结果:"); g.DFS(2); } } ``` 上述代码中,我们首先定义了一个`Graph`类来表示图,其中使用邻接表来存储图的结构。然后,我们实现了`DFSUtil`方法来递归地进行DFS遍历,并在遍历过中打印节点的值。最后,在`main`方法中创建一个图对象,并调用`DFS`方法来进行DFS遍历。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值