洛谷 P1706 Java解法

题目出处点这里

在这里插入图片描述

有两种方法,但本质都是深度优先搜索deep first search

第一种(讲解见代码):

package violence;

import java.util.Scanner;

public class P1706_1 {
	
	static int n;
	static boolean[] isUsed = new boolean[10];//用来判断相应数字有没有被使用过
	static int[] res = new int[10]; //用来存储结果
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		dfs(0);
	}
	
	public static void dfs(int now) {//now代表现在res数组里有几个数字,也可以理解为当前索引
		if (now == n ) {//当now == n 时,就说明已经满了,直接输出即可
			print();
			return;
		}
		
		for (int i = 0; i < n; i++) {
			if (!isUsed[i]) {//判断是否被用过
				isUsed[i] = true;//既然进来了,就设为使用过了
				res[now] = i + 1;//因为n是1-9,所有i+1
				dfs(now+1);//加入后now+1
				//最后回溯是对isUsed[i]回溯;如果写成isUsed[now]的话
				//由于每次回溯时now==n,所以写成isUsed[now]的话其实每次就只把最后一个数置为false
				isUsed[i] = false;//回溯
			}
		}
	}
	
	//输出
	public static void print() {
		for (int i = 0; i < n; i++) {
			System.out.print("    "+res[i]);
		}
		System.out.println();
	}
}

第二种(讲解见代码):

为方便输出用ArrayList代替了stack

package violence;

import java.util.ArrayList;
import java.util.Scanner;

public class P1706_2 {
	
	static int n;
	static ArrayList<Integer> list = new ArrayList<Integer>();
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		n = sc.nextInt();
		int arr[] = new int[n];
		for (int i = 0; i < arr.length; i++) {
			arr[i] = i + 1;
		}
		dfs(0);
	}
	
	/**
	 * 
	 * @param has 代表目前list里有多少个数
	 */
	public static void dfs(int has) {//has代表list有多少个数
		if (has == n) {//满了就输出
			print();
			return;
		}
		
		for (int i = 0; i < n; i++) {
			if (!list.contains(i+1)) {//避免数字重复
				list.add(i+1);//直接加入数组
				dfs(has+1);//进行下一次递归,has+1
				list.remove(list.size() - 1);//把队尾数字去掉
			}
		}
	}
	
	//输出
	public static void print() {
		for (int i = 0; i < n; i++) {
			System.out.print("    "+list.get(i));
		}
		System.out.println();
	}
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值