Java全排列模板及例题(dfs)

模板一

参考博客

package 蓝桥杯;

import java.util.Arrays;

public class 全排列 {
    public static void main(String[] args) {
        perm(new int[]{1,2,3},0,2);
    }
    public static void perm(int[] array,int start,int end) {
        if(start==end) {
            System.out.println(Arrays.toString(array));
        } else {
            for (int i = start; i <= end; i++) {
                //1,2,3的全排列这块相当于将其中一个提了出来,下次递归从start+1开始
                swap(array,start,i);
                perm(array,start+1,end);
                //这块是复原数组,为了保证下次另外的同级递归使用数组不会出错
                //这块可以通过树来理解,每次回退一步操作,交换回去
                swap(array,start,i);
            }
        }
    }
    public static void swap(int[] array,int i,int j) {
        int temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }
}

模板二

package 蓝桥杯;

import java.util.Arrays;

public class 全排列1 {
    static int[] arr ={1,2,3,4};
    public static void main(String[] args) {
        dfs(0);
    }
    public static void dfs(int index){
        if(index==4){
            System.out.println(Arrays.toString(arr));
        }else{
            for(int i=index;i<arr.length;i++){
                swap(index,i);
                dfs(index+1);
                swap(index,i);
            }
        }
    }
    public static void swap(int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;

    }
}

例题1、带分数

在这里插入图片描述

这个题的主要思路就是将1-9的数字进行全排列,然后用两个指针将他们分开为三个数,然后判断是否满足题目要求。
由于两个数相除比较麻烦,所以将本题判断的条件由 N = a + b/c, 转化为 Nc = ac +b
在这里插入图片描述

package 蓝桥杯;


import java.util.Scanner;


public class 带分数 {
    static  int num;
    static  int count = 0;
    static int[] arr = {1,2,3,4,5,6,7,8,9};
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        num = sc.nextInt();
        dfs(0,8);
        System.out.println(count);
    }
    //对1 2 3 4 5 6 7 8 9进行全排列
    public static void dfs(int start,int end){
        if(start==end) {
            check();
        }else {
            for(int i = start; i<=end; i++){
                swap(start,i);
                dfs(start+1,8);
                swap(start,i);
            }
        }

    }
    // check 函数用来判断是否满足N*c = a*c +b的要求
    public static void check(){
        for(int i = 0; i<=6;i++){
            for(int j =i+1; j<=7;j++){
               int a = getval(0,i);
               int b = getval(i+1,j);
               int c = getval(j+1,8);
                if(num*c==a*c+b ) count++;
            }
        }
    }

    public static int getval(int i, int j){
        int shu=0;
        for(;i<=j;i++){
            shu = shu*10 + arr[i];
        }
        return shu;
    }
    public static void swap(int i, int k){
        int temp = arr[i];
        arr[i] = arr[k];
        arr[k] = temp;

    }

}

例题二、算式900

在这里插入图片描述

这个题和上面的题差不多,只不过是把对1-9的数全排列变成对0-9的数全排列然后判断是否满足条件
在这里我忘记筛选以0开头的数了,反正是个填空题,最后就人工排除了,如果想筛选的话只需要判断数组0、4、8的位置是否是0就可以了

这是这个题的运算结果,得到三个结果,人工排除了第三个,因为第三个是有开头是0的数,第三个的真实式子是这样的
(7153 - 6928) * 04 == 900
在这里插入图片描述

package 蓝桥杯;

import java.util.Scanner;

public class 算数900 {
    static int[] arr ={0,1,2,3,4,5,6,7,8,9};
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        dfs(0);
        scan.close();
    }
    public static void dfs(int index){
        if(index==10){
            check();
        }else{
            for(int i=index;i<arr.length;i++){
                swap(index,i);
                dfs(index+1);
                swap(index,i);
            }
        }
    }
    public static void check(){
        int a = getnum(0,3);
        int b = getnum(4,7);
        int c = getnum(8,9);
        if((a-b)*c==900) System.out.println("("+a+"-"+b+")"+"*"+c+"==900");

    }
    public static int getnum(int i, int j){
        int num = 0;
        for(int k =i; k<=j;k++){
            num = num*10+arr[k];
        }
        return num;

    }
    public static void swap(int i,int j){
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梦森森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值