全排列筛选(java)

蓝桥杯-全排列筛选(java)

蓝桥杯每年必考全排列筛选,一般为填空题;

 

可以使用for循环暴力破解,但是代码相对较长,也比较乱,不建议使用;

这里使用递归来解决,代码量相对较少,也很好理解;

如下为:0-9的全排列个数;

如需实现从0-9里选n个数只需要改变dfs的参数k的传值就可以了;

全排列模板代码:

public class Main {
    static int count=0;// 计数器
    public static void main(String[] args) {
        int[] arr = new int []{0,1, 2, 3,4,5,6,7,8,9};//数组元素为需要全排列的数,如果想排列字母改成char数组传入就可以了
        dfs(arr, 0, 10);// 改成dfs(arr,0,5)就是从中选5个数全排列,之后输出语句选数组前五个输出即可
        System.out.println(count);
    }
    // 递归全排列
    public static void dfs(int arr[], int num, int k) {
        if (num == k) {// 递归出口
            if (panDuan(arr)) {// 筛选
                // 里面可以输出,计数,根据具体情况填写
                count++;
                /*
                  for (int i = 0; i < k; i++){
                      System.out.print(arr[i]);        
           }System.out.println();
*/

 


            }
        }
        for (int i = num; i < arr.length; i++) {
            swap(arr, num, i);
            dfs(arr, num + 1, k);
            swap(arr, num, i);
        }
    }
    // 筛选方法
    private static boolean panDuan(int[] arr) {
      // 根据题目的条件判断筛选
return false; } // 数组元素交换,注:变量之间不可以用函数交换 public static void swap(int[] arr, int i, int j) { int t = arr[i]; arr[i] = arr[j]; arr[j] = t; } }

例题:

标题:五星填数

如【图1.png】的五星图案节点填上数字:1~12,除去7和11。
每条直线上数字和相等。
如图就是恰当的填法。
请你利用计算机搜索所有可能的填法有多少种。


注意:旋转或镜像后相同的算同一种填法。

注意:这里旋转或镜像:旋转有5种相同状态(旋转360度过程中遇到五次一致的状态),每种状态有2种镜像(二维图形镜像一般都是2种),所以结果要除以10;

public class Demo2 {
        static int count=0;
        public static void main(String[] args) {
            int arr[]=new int[]{1,2,3,4,5,6,8,9,10,12};//除去7,11
            dfs(arr,0,10);
            System.out.println(count/10);
        }
        private static void dfs(int[] arr, int num, int k) {
            // TODO Auto-generated method stub
            if(num==k){
                if(panDuan(arr)){
                    count++;// 条件达到,count++;
                }
            }
            for(int i=num;i<arr.length;i++){
                swap(arr,num,i);
                dfs(arr,num+1,k);
                swap(arr,num,i);
            }
        }
        private static void swap(int[] arr, int num, int i) {
            // TODO Auto-generated method stub
            int temp=arr[num];
            arr[num]=arr[i];
            arr[i]=temp;
        }
        private static boolean panDuan(int[] arr) {
            // TODO Auto-generated method stub
            //判断五条边相等
            int a1=arr[0]+arr[2]+arr[5]+arr[8];
            int a2=arr[1]+arr[2]+arr[3]+arr[4];
            int a3=arr[0]+arr[3]+arr[6]+arr[9];
            int a4=arr[1]+arr[7]+arr[5]+arr[9];
            int a5=arr[4]+arr[6]+arr[7]+arr[8];
        /*       0
             1  2 3  4
               5   6
                 7
             8       9*/
            if(a1==a2&&a2==a3&&a3==a4&&a4==a5){
                return true;
            }else
            return false;
        }
}

 

 
错误或不足的地方欢迎指正!!

最后分享一个喜欢的句子:
其实你我都改变不了什么。萍水相逢,缘开缘灭。

posted @ 2017-12-27 19:00  杨守鹤  阅读(597)  评论(0编辑  收藏  举报