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;
    }
}

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
/* * (有向)图的深度优先遍历算法模板 */ package dsa; public abstract class DFS extends GraphTraverse { //变量 protected static int clock = 0;//遍历过程中使用的计时钟 //构造方法 public DFS(Graph g) { super(g); } //深度优先遍历算法 protected Object traverse(Vertex v, Object info) {//从顶点v出发,做深度优先查找 if (UNDISCOVERED != v.getStatus()) return null;//跳过已访问过的顶点(针对非连通图) v.setDStamp(clock++); v.setStatus(DISCOVERED); visit(v, info);//访问当前顶点 for (Iterator it = v.outEdges(); it.hasNext();) {//检查与顶点v Edge e = (Edge)it.getNext();//通过边e = (v, u) Vertex u = (Vertex)e.getVPosInV(1).getElem();//相联的每一顶点u switch (u.getStatus()) {//根据u当前的不同状态,分别做相应处理 case UNDISCOVERED ://若u尚未被发现,则 e.setType(TREE);//e被归类为“树边” traverse(u, info);//从u出发,继续做深度优先查找 break; case DISCOVERED ://若u已经被发现,但对其访问尚未结束,则 e.setType(BACKWARD);//将e归类为“后向跨边” break; default ://VISITED,即对u的访问已经结束 if (u.getDStamp() < v.getDStamp())//若相对于v,u被发现得更早,则 e.setType(CROSS);//将e归类为“横跨边” else//否则 e.setType(FORWARD);//将e归类为“前向跨边” break; } }//至此,v的所有邻居都已访问结束,故 v.setFStamp(clock++); v.setStatus(VISITED);//将v标记为VISITED return null;//然后回溯 } }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

梦森森

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

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

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

打赏作者

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

抵扣说明:

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

余额充值